diff options
author | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-07-22 11:13:41 +0800 |
---|---|---|
committer | Hsiu-Chang Chen <hsiuchangchen@google.com> | 2022-07-22 11:13:41 +0800 |
commit | eb93a5121d88779e93a2b361ac0ddac1e98c02e8 (patch) | |
tree | 336c9598dab15a5e7e6e750e86cfaf0c60a6a766 | |
parent | 79861d3fe23093fe704c1d341642b434fb323aa6 (diff) | |
download | wlan-eb93a5121d88779e93a2b361ac0ddac1e98c02e8.tar.gz |
wlan: create wifi_hal for wcn6740
The original wifi_hal for legacy projects is so old that
we met lots of issues in wcn6740. Create another wifi_hal
for wcn6740 that uses latest code and keep using the old
wifi_hal code for the legacy projects.
Bug: 213413875
Test: Regression Test
Change-Id: Ibb3c748254c3e5472b3218bda34c88f79d343dae
147 files changed, 67255 insertions, 1 deletions
@@ -1,4 +1,8 @@ #set TARGET_USES_HARDWARE_QCOM_WLAN to false to disable this project. ifneq ($(TARGET_USES_HARDWARE_QCOM_WLAN),false) -include $(call all-subdir-makefiles) + ifneq ($(filter lynx,$(TARGET_DEVICE)),) + include $(call all-named-subdir-makefiles,wcn6740) + else + include $(call all-named-subdir-makefiles,legacy) + endif endif diff --git a/legacy/Android.mk b/legacy/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/legacy/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/cld80211-lib/Android.mk b/legacy/cld80211-lib/Android.mk index e97917a..e97917a 100644 --- a/cld80211-lib/Android.mk +++ b/legacy/cld80211-lib/Android.mk diff --git a/cld80211-lib/cld80211_lib.c b/legacy/cld80211-lib/cld80211_lib.c index b34ed28..b34ed28 100644 --- a/cld80211-lib/cld80211_lib.c +++ b/legacy/cld80211-lib/cld80211_lib.c diff --git a/cld80211-lib/cld80211_lib.h b/legacy/cld80211-lib/cld80211_lib.h index 2503f2a..2503f2a 100644 --- a/cld80211-lib/cld80211_lib.h +++ b/legacy/cld80211-lib/cld80211_lib.h diff --git a/qcwcn/Android.mk b/legacy/qcwcn/Android.mk index be3bb25..be3bb25 100644 --- a/qcwcn/Android.mk +++ b/legacy/qcwcn/Android.mk diff --git a/qcwcn/config/Android.mk b/legacy/qcwcn/config/Android.mk index 1c1622d..1c1622d 100644 --- a/qcwcn/config/Android.mk +++ b/legacy/qcwcn/config/Android.mk diff --git a/qcwcn/wcnss-service/Android.mk b/legacy/qcwcn/wcnss-service/Android.mk index 0425563..0425563 100644 --- a/qcwcn/wcnss-service/Android.mk +++ b/legacy/qcwcn/wcnss-service/Android.mk diff --git a/qcwcn/wcnss-service/wcnss_qmi_client.c b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.c index 28acce1..28acce1 100644 --- a/qcwcn/wcnss-service/wcnss_qmi_client.c +++ b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.c diff --git a/qcwcn/wcnss-service/wcnss_qmi_client.h b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.h index 51fefac..51fefac 100644 --- a/qcwcn/wcnss-service/wcnss_qmi_client.h +++ b/legacy/qcwcn/wcnss-service/wcnss_qmi_client.h diff --git a/qcwcn/wcnss-service/wcnss_service.c b/legacy/qcwcn/wcnss-service/wcnss_service.c index f0c82ea..f0c82ea 100644 --- a/qcwcn/wcnss-service/wcnss_service.c +++ b/legacy/qcwcn/wcnss-service/wcnss_service.c diff --git a/qcwcn/wifi_hal/Android.mk b/legacy/qcwcn/wifi_hal/Android.mk index 5761e5b..5761e5b 100644 --- a/qcwcn/wifi_hal/Android.mk +++ b/legacy/qcwcn/wifi_hal/Android.mk diff --git a/qcwcn/wifi_hal/common.cpp b/legacy/qcwcn/wifi_hal/common.cpp index 3d72e76..3d72e76 100644 --- a/qcwcn/wifi_hal/common.cpp +++ b/legacy/qcwcn/wifi_hal/common.cpp diff --git a/qcwcn/wifi_hal/common.h b/legacy/qcwcn/wifi_hal/common.h index 401921b..401921b 100644 --- a/qcwcn/wifi_hal/common.h +++ b/legacy/qcwcn/wifi_hal/common.h diff --git a/qcwcn/wifi_hal/cpp_bindings.cpp b/legacy/qcwcn/wifi_hal/cpp_bindings.cpp index 6efec5a..6efec5a 100644 --- a/qcwcn/wifi_hal/cpp_bindings.cpp +++ b/legacy/qcwcn/wifi_hal/cpp_bindings.cpp diff --git a/qcwcn/wifi_hal/cpp_bindings.h b/legacy/qcwcn/wifi_hal/cpp_bindings.h index 71d8da9..71d8da9 100644 --- a/qcwcn/wifi_hal/cpp_bindings.h +++ b/legacy/qcwcn/wifi_hal/cpp_bindings.h diff --git a/qcwcn/wifi_hal/gscan.cpp b/legacy/qcwcn/wifi_hal/gscan.cpp index 22910dc..22910dc 100644 --- a/qcwcn/wifi_hal/gscan.cpp +++ b/legacy/qcwcn/wifi_hal/gscan.cpp diff --git a/qcwcn/wifi_hal/gscan_event_handler.cpp b/legacy/qcwcn/wifi_hal/gscan_event_handler.cpp index 074d64b..074d64b 100644 --- a/qcwcn/wifi_hal/gscan_event_handler.cpp +++ b/legacy/qcwcn/wifi_hal/gscan_event_handler.cpp diff --git a/qcwcn/wifi_hal/gscan_event_handler.h b/legacy/qcwcn/wifi_hal/gscan_event_handler.h index 5384db8..5384db8 100644 --- a/qcwcn/wifi_hal/gscan_event_handler.h +++ b/legacy/qcwcn/wifi_hal/gscan_event_handler.h diff --git a/qcwcn/wifi_hal/gscancommand.h b/legacy/qcwcn/wifi_hal/gscancommand.h index dc48ef6..dc48ef6 100644 --- a/qcwcn/wifi_hal/gscancommand.h +++ b/legacy/qcwcn/wifi_hal/gscancommand.h diff --git a/qcwcn/wifi_hal/ifaceeventhandler.cpp b/legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp index 82f1add..82f1add 100644 --- a/qcwcn/wifi_hal/ifaceeventhandler.cpp +++ b/legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp diff --git a/qcwcn/wifi_hal/ifaceeventhandler.h b/legacy/qcwcn/wifi_hal/ifaceeventhandler.h index d055a1b..d055a1b 100644 --- a/qcwcn/wifi_hal/ifaceeventhandler.h +++ b/legacy/qcwcn/wifi_hal/ifaceeventhandler.h diff --git a/qcwcn/wifi_hal/list.cpp b/legacy/qcwcn/wifi_hal/list.cpp index 966da2e..966da2e 100644 --- a/qcwcn/wifi_hal/list.cpp +++ b/legacy/qcwcn/wifi_hal/list.cpp diff --git a/qcwcn/wifi_hal/list.h b/legacy/qcwcn/wifi_hal/list.h index 90d344c..90d344c 100644 --- a/qcwcn/wifi_hal/list.h +++ b/legacy/qcwcn/wifi_hal/list.h diff --git a/qcwcn/wifi_hal/llstats.cpp b/legacy/qcwcn/wifi_hal/llstats.cpp index 8e827e2..8e827e2 100644 --- a/qcwcn/wifi_hal/llstats.cpp +++ b/legacy/qcwcn/wifi_hal/llstats.cpp diff --git a/qcwcn/wifi_hal/llstatscommand.h b/legacy/qcwcn/wifi_hal/llstatscommand.h index 86b9672..86b9672 100644 --- a/qcwcn/wifi_hal/llstatscommand.h +++ b/legacy/qcwcn/wifi_hal/llstatscommand.h diff --git a/qcwcn/wifi_hal/nan.cpp b/legacy/qcwcn/wifi_hal/nan.cpp index 9e74cea..9e74cea 100644 --- a/qcwcn/wifi_hal/nan.cpp +++ b/legacy/qcwcn/wifi_hal/nan.cpp diff --git a/qcwcn/wifi_hal/nan_cert.h b/legacy/qcwcn/wifi_hal/nan_cert.h index 85b7073..85b7073 100644 --- a/qcwcn/wifi_hal/nan_cert.h +++ b/legacy/qcwcn/wifi_hal/nan_cert.h diff --git a/qcwcn/wifi_hal/nan_i.h b/legacy/qcwcn/wifi_hal/nan_i.h index 78cdb1a..78cdb1a 100644 --- a/qcwcn/wifi_hal/nan_i.h +++ b/legacy/qcwcn/wifi_hal/nan_i.h diff --git a/qcwcn/wifi_hal/nan_ind.cpp b/legacy/qcwcn/wifi_hal/nan_ind.cpp index 1fe651d..1fe651d 100644 --- a/qcwcn/wifi_hal/nan_ind.cpp +++ b/legacy/qcwcn/wifi_hal/nan_ind.cpp diff --git a/qcwcn/wifi_hal/nan_req.cpp b/legacy/qcwcn/wifi_hal/nan_req.cpp index 4452783..4452783 100644 --- a/qcwcn/wifi_hal/nan_req.cpp +++ b/legacy/qcwcn/wifi_hal/nan_req.cpp diff --git a/qcwcn/wifi_hal/nan_rsp.cpp b/legacy/qcwcn/wifi_hal/nan_rsp.cpp index f0b9b1c..f0b9b1c 100644 --- a/qcwcn/wifi_hal/nan_rsp.cpp +++ b/legacy/qcwcn/wifi_hal/nan_rsp.cpp diff --git a/qcwcn/wifi_hal/nancommand.h b/legacy/qcwcn/wifi_hal/nancommand.h index 8a16248..8a16248 100644 --- a/qcwcn/wifi_hal/nancommand.h +++ b/legacy/qcwcn/wifi_hal/nancommand.h diff --git a/qcwcn/wifi_hal/pkt_stats.h b/legacy/qcwcn/wifi_hal/pkt_stats.h index d4348cd..d4348cd 100644 --- a/qcwcn/wifi_hal/pkt_stats.h +++ b/legacy/qcwcn/wifi_hal/pkt_stats.h diff --git a/qcwcn/wifi_hal/qca-vendor_copy.h b/legacy/qcwcn/wifi_hal/qca-vendor_copy.h index 24a31a3..24a31a3 100644 --- a/qcwcn/wifi_hal/qca-vendor_copy.h +++ b/legacy/qcwcn/wifi_hal/qca-vendor_copy.h diff --git a/qcwcn/wifi_hal/radio_mode.cpp b/legacy/qcwcn/wifi_hal/radio_mode.cpp index 9ed211f..9ed211f 100644 --- a/qcwcn/wifi_hal/radio_mode.cpp +++ b/legacy/qcwcn/wifi_hal/radio_mode.cpp diff --git a/qcwcn/wifi_hal/radio_mode.h b/legacy/qcwcn/wifi_hal/radio_mode.h index 4bb83f1..4bb83f1 100644 --- a/qcwcn/wifi_hal/radio_mode.h +++ b/legacy/qcwcn/wifi_hal/radio_mode.h diff --git a/qcwcn/wifi_hal/rb_wrapper.cpp b/legacy/qcwcn/wifi_hal/rb_wrapper.cpp index 9017d21..9017d21 100644 --- a/qcwcn/wifi_hal/rb_wrapper.cpp +++ b/legacy/qcwcn/wifi_hal/rb_wrapper.cpp diff --git a/qcwcn/wifi_hal/rb_wrapper.h b/legacy/qcwcn/wifi_hal/rb_wrapper.h index 6160ebc..6160ebc 100644 --- a/qcwcn/wifi_hal/rb_wrapper.h +++ b/legacy/qcwcn/wifi_hal/rb_wrapper.h diff --git a/qcwcn/wifi_hal/ring_buffer.cpp b/legacy/qcwcn/wifi_hal/ring_buffer.cpp index 1a65bb6..1a65bb6 100644 --- a/qcwcn/wifi_hal/ring_buffer.cpp +++ b/legacy/qcwcn/wifi_hal/ring_buffer.cpp diff --git a/qcwcn/wifi_hal/ring_buffer.h b/legacy/qcwcn/wifi_hal/ring_buffer.h index 3a310b7..3a310b7 100644 --- a/qcwcn/wifi_hal/ring_buffer.h +++ b/legacy/qcwcn/wifi_hal/ring_buffer.h diff --git a/qcwcn/wifi_hal/roam.cpp b/legacy/qcwcn/wifi_hal/roam.cpp index f2678d0..f2678d0 100644 --- a/qcwcn/wifi_hal/roam.cpp +++ b/legacy/qcwcn/wifi_hal/roam.cpp diff --git a/qcwcn/wifi_hal/roamcommand.h b/legacy/qcwcn/wifi_hal/roamcommand.h index 9de90b2..9de90b2 100644 --- a/qcwcn/wifi_hal/roamcommand.h +++ b/legacy/qcwcn/wifi_hal/roamcommand.h diff --git a/qcwcn/wifi_hal/rssi_monitor.cpp b/legacy/qcwcn/wifi_hal/rssi_monitor.cpp index 832bbc3..832bbc3 100644 --- a/qcwcn/wifi_hal/rssi_monitor.cpp +++ b/legacy/qcwcn/wifi_hal/rssi_monitor.cpp diff --git a/qcwcn/wifi_hal/rssi_monitor.h b/legacy/qcwcn/wifi_hal/rssi_monitor.h index c6ea692..c6ea692 100644 --- a/qcwcn/wifi_hal/rssi_monitor.h +++ b/legacy/qcwcn/wifi_hal/rssi_monitor.h diff --git a/qcwcn/wifi_hal/rtt.cpp b/legacy/qcwcn/wifi_hal/rtt.cpp index b295ab6..b295ab6 100644 --- a/qcwcn/wifi_hal/rtt.cpp +++ b/legacy/qcwcn/wifi_hal/rtt.cpp diff --git a/qcwcn/wifi_hal/sync.h b/legacy/qcwcn/wifi_hal/sync.h index eaa9f11..eaa9f11 100644 --- a/qcwcn/wifi_hal/sync.h +++ b/legacy/qcwcn/wifi_hal/sync.h diff --git a/qcwcn/wifi_hal/tdls.cpp b/legacy/qcwcn/wifi_hal/tdls.cpp index f12816f..f12816f 100644 --- a/qcwcn/wifi_hal/tdls.cpp +++ b/legacy/qcwcn/wifi_hal/tdls.cpp diff --git a/qcwcn/wifi_hal/tdlsCommand.h b/legacy/qcwcn/wifi_hal/tdlsCommand.h index 565e9b3..565e9b3 100755 --- a/qcwcn/wifi_hal/tdlsCommand.h +++ b/legacy/qcwcn/wifi_hal/tdlsCommand.h diff --git a/qcwcn/wifi_hal/vendor_definitions.h b/legacy/qcwcn/wifi_hal/vendor_definitions.h index d542148..d542148 100644 --- a/qcwcn/wifi_hal/vendor_definitions.h +++ b/legacy/qcwcn/wifi_hal/vendor_definitions.h diff --git a/qcwcn/wifi_hal/wifi_hal.cpp b/legacy/qcwcn/wifi_hal/wifi_hal.cpp index cb4b8e7..cb4b8e7 100644 --- a/qcwcn/wifi_hal/wifi_hal.cpp +++ b/legacy/qcwcn/wifi_hal/wifi_hal.cpp diff --git a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c index 61834fc..61834fc 100644 --- a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c +++ b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c diff --git a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h index dbfba56..dbfba56 100644 --- a/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h +++ b/legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h diff --git a/qcwcn/wifi_hal/wificonfig.cpp b/legacy/qcwcn/wifi_hal/wificonfig.cpp index 7ff323c..7ff323c 100644 --- a/qcwcn/wifi_hal/wificonfig.cpp +++ b/legacy/qcwcn/wifi_hal/wificonfig.cpp diff --git a/qcwcn/wifi_hal/wificonfigcommand.h b/legacy/qcwcn/wifi_hal/wificonfigcommand.h index bbe89a0..bbe89a0 100644 --- a/qcwcn/wifi_hal/wificonfigcommand.h +++ b/legacy/qcwcn/wifi_hal/wificonfigcommand.h diff --git a/qcwcn/wifi_hal/wifihal_internal.h b/legacy/qcwcn/wifi_hal/wifihal_internal.h index 5cc78c3..5cc78c3 100755 --- a/qcwcn/wifi_hal/wifihal_internal.h +++ b/legacy/qcwcn/wifi_hal/wifihal_internal.h diff --git a/qcwcn/wifi_hal/wifihal_vendor.cpp b/legacy/qcwcn/wifi_hal/wifihal_vendor.cpp index f408342..f408342 100644 --- a/qcwcn/wifi_hal/wifihal_vendor.cpp +++ b/legacy/qcwcn/wifi_hal/wifihal_vendor.cpp diff --git a/qcwcn/wifi_hal/wifihal_vendorcommand.h b/legacy/qcwcn/wifi_hal/wifihal_vendorcommand.h index 2a73902..2a73902 100644 --- a/qcwcn/wifi_hal/wifihal_vendorcommand.h +++ b/legacy/qcwcn/wifi_hal/wifihal_vendorcommand.h diff --git a/qcwcn/wifi_hal/wifilogger.cpp b/legacy/qcwcn/wifi_hal/wifilogger.cpp index ee9efa1..ee9efa1 100644 --- a/qcwcn/wifi_hal/wifilogger.cpp +++ b/legacy/qcwcn/wifi_hal/wifilogger.cpp diff --git a/qcwcn/wifi_hal/wifilogger_diag.cpp b/legacy/qcwcn/wifi_hal/wifilogger_diag.cpp index 09ac928..09ac928 100644 --- a/qcwcn/wifi_hal/wifilogger_diag.cpp +++ b/legacy/qcwcn/wifi_hal/wifilogger_diag.cpp diff --git a/qcwcn/wifi_hal/wifilogger_diag.h b/legacy/qcwcn/wifi_hal/wifilogger_diag.h index fc23cb7..fc23cb7 100644 --- a/qcwcn/wifi_hal/wifilogger_diag.h +++ b/legacy/qcwcn/wifi_hal/wifilogger_diag.h diff --git a/qcwcn/wifi_hal/wifilogger_event_defs.h b/legacy/qcwcn/wifi_hal/wifilogger_event_defs.h index c49a3b6..c49a3b6 100644 --- a/qcwcn/wifi_hal/wifilogger_event_defs.h +++ b/legacy/qcwcn/wifi_hal/wifilogger_event_defs.h diff --git a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/legacy/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h index 422abd3..422abd3 100644 --- a/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h +++ b/legacy/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h diff --git a/qcwcn/wifi_hal/wifiloggercmd.h b/legacy/qcwcn/wifi_hal/wifiloggercmd.h index f9535ce..f9535ce 100644 --- a/qcwcn/wifi_hal/wifiloggercmd.h +++ b/legacy/qcwcn/wifi_hal/wifiloggercmd.h diff --git a/qcwcn/wpa_supplicant_8_lib/Android.mk b/legacy/qcwcn/wpa_supplicant_8_lib/Android.mk index e756800..e756800 100644 --- a/qcwcn/wpa_supplicant_8_lib/Android.mk +++ b/legacy/qcwcn/wpa_supplicant_8_lib/Android.mk diff --git a/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD b/legacy/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD index e69de29..e69de29 100644 --- a/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD +++ b/legacy/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD diff --git a/qcwcn/wpa_supplicant_8_lib/NOTICE b/legacy/qcwcn/wpa_supplicant_8_lib/NOTICE index f9d25ea..f9d25ea 100644 --- a/qcwcn/wpa_supplicant_8_lib/NOTICE +++ b/legacy/qcwcn/wpa_supplicant_8_lib/NOTICE diff --git a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/legacy/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c index c5d1c93..c5d1c93 100644 --- a/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c +++ b/legacy/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c diff --git a/wcn6740/Android.mk b/wcn6740/Android.mk new file mode 100644 index 0000000..6695cef --- /dev/null +++ b/wcn6740/Android.mk @@ -0,0 +1,6 @@ +# TODO: Find a better way to separate build configs for ADP vs non-ADP devices +QCOM_WLAN_ROOT := $(call my-dir) + +ifneq ($(BOARD_IS_AUTOMOTIVE),true) +include $(call all-subdir-makefiles) +endif diff --git a/wcn6740/cld80211-lib/Android.mk b/wcn6740/cld80211-lib/Android.mk new file mode 100644 index 0000000..404c116 --- /dev/null +++ b/wcn6740/cld80211-lib/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH := $(call my-dir) + +# ================================= +# copy header +# ================================= +include $(CLEAR_VARS) + +LOCAL_MODULE := libcld80211_headers +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +LOCAL_VENDOR_MODULE := true +include $(BUILD_HEADER_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libcld80211 +LOCAL_CLANG := true +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES += $(LOCAL_PATH) \ + external/libnl/include +LOCAL_SHARED_LIBRARIES := libcutils libnl liblog +LOCAL_SRC_FILES := cld80211_lib.c +LOCAL_CFLAGS += -Wall -Werror -Wno-unused-parameter +LOCAL_HEADER_LIBRARIES := libcld80211_headers +LOCAL_VENDOR_MODULE := true +include $(BUILD_SHARED_LIBRARY) + diff --git a/wcn6740/cld80211-lib/Makefile.am b/wcn6740/cld80211-lib/Makefile.am new file mode 100644 index 0000000..19cdc49 --- /dev/null +++ b/wcn6740/cld80211-lib/Makefile.am @@ -0,0 +1,27 @@ +# Makefile.am - Automake script for cld80211-lib +ACLOCAL_AMFLAGS = -I m4 + +AM_CFLAGS = -Wall + +if DEBUG +AM_CFLAGS += -g +else +AM_CFLAGS += -O2 +endif + +AM_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast \ + -Wno-maybe-uninitialized -Wno-parentheses -DLE_BUILD \ + -D_GNU_SOURCE=1 + +h_sources = cld80211_lib.h +library_includedir = $(pkgincludedir) +library_include_HEADERS = $(h_sources) + +libcld80211_la_SOURCES = cld80211_lib.c +libcld80211_la_CFLAGS = ${AM_CFLAGS} ${LIBNL_CFLAGS} +libcld80211_la_LIBADD = ${LIBNL_LIBS} +lib_LTLIBRARIES = libcld80211.la + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = cld80211-lib.pc +EXTRA_DIST = $(pkgconfig_DATA) diff --git a/wcn6740/cld80211-lib/cld80211-lib.pc.in b/wcn6740/cld80211-lib/cld80211-lib.pc.in new file mode 100644 index 0000000..c611c64 --- /dev/null +++ b/wcn6740/cld80211-lib/cld80211-lib.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: cld80211-lib +Description: "cld80211 Library" +Version: @VERSION@ +Libs: -L${libdir} -lcld80211 +Cflags: -I${includedir}/@PACKAGE@ diff --git a/wcn6740/cld80211-lib/cld80211_lib.c b/wcn6740/cld80211-lib/cld80211_lib.c new file mode 100644 index 0000000..bc082a9 --- /dev/null +++ b/wcn6740/cld80211-lib/cld80211_lib.c @@ -0,0 +1,523 @@ +/* + * Driver interaction with Linux nl80211/cfg80211 + * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2004, Instant802 Networks, Inc. + * Copyright (c) 2005-2006, Devicescape Software, Inc. + * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net> + * Copyright (c) 2009-2010, Atheros Communications + * Copyright (c) 2017-2018, The Linux Foundation. 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 + * * 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 + * + */ + +#include <errno.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/pkt_sched.h> +#include <unistd.h> +#include "cld80211_lib.h" + +#ifndef LE_BUILD + #include <log/log.h> + #undef LOG_TAG + #define LOG_TAG "CLD80211" +#else + #include <stdlib.h> + #include <syslog.h> + #include <unistd.h> + #define ALOGI(fmt, args...) syslog(LOG_INFO, fmt, ## args) + #define ALOGE(fmt, args...) syslog(LOG_ERR, fmt, ## args) + extern const char *__progname; + const char *getprogname() { return (__progname); } +#endif + +#define SOCK_BUF_SIZE (256*1024) + +struct family_data { + const char *group; + int id; +}; + + +static struct nl_sock * create_nl_socket(int protocol) +{ + struct nl_sock *sock; + + sock = nl_socket_alloc(); + if (sock == NULL) { + ALOGE("%s: Failed to create NL socket, err: %d", + getprogname(), errno); + return NULL; + } + + if (nl_connect(sock, protocol)) { + ALOGE("%s: Could not connect sock, err: %d", + getprogname(), errno); + nl_socket_free(sock); + return NULL; + } + + return sock; +} + + +static int init_exit_sockets(struct cld80211_ctx *ctx) +{ + ctx->exit_sockets[0] = -1; + ctx->exit_sockets[1] = -1; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, &ctx->exit_sockets[0]) == -1) { + ALOGE("%s: Failed to create exit socket pair", getprogname()); + return -1; + } + ALOGI("%s: initialized exit socket pair", getprogname()); + + return 0; +} + + +static void cleanup_exit_sockets(struct cld80211_ctx *ctx) +{ + if (ctx->exit_sockets[0] >= 0) { + close(ctx->exit_sockets[0]); + ctx->exit_sockets[0] = -1; + } + + if (ctx->exit_sockets[1] >= 0) { + close(ctx->exit_sockets[1]); + ctx->exit_sockets[1] = -1; + } +} + + +void exit_cld80211_recv(struct cld80211_ctx *ctx) +{ + if (!ctx) { + ALOGE("%s: ctx is NULL: %s", getprogname(), __func__); + return; + } + TEMP_FAILURE_RETRY(write(ctx->exit_sockets[0], "E", 1)); + ALOGI("%s: Sent msg on exit sock to unblock poll()", getprogname()); +} + + +/* Event handlers */ +static int response_handler(struct nl_msg *msg, void *arg) +{ + UNUSED(msg); + UNUSED(arg); + ALOGI("%s: Received nlmsg response: no callback registered;drop it", + getprogname()); + + return NL_SKIP; +} + + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *err = (int *)arg; + *err = 0; + UNUSED(msg); + return NL_STOP; +} + + +static int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + *ret = 0; + UNUSED(msg); + return NL_SKIP; +} + + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = (int *)arg; + *ret = err->error; + + UNUSED(nla); + ALOGE("%s: error_handler received : %d", getprogname(), err->error); + return NL_SKIP; +} + + +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + UNUSED(msg); + UNUSED(arg); + return NL_OK; +} + + +int cld80211_recv_msg(struct nl_sock *sock, struct nl_cb *cb) +{ + if (!sock || !cb) { + ALOGE("%s: %s is NULL", getprogname(), sock?"cb":"sock"); + return -EINVAL; + } + + int res = nl_recvmsgs(sock, cb); + if(res) + ALOGE("%s: Error :%d while reading nl msg , err: %d", + getprogname(), res, errno); + return res; +} + + +static void cld80211_handle_event(int events, struct nl_sock *sock, + struct nl_cb *cb) +{ + if (events & POLLERR) { + ALOGE("%s: Error reading from socket", getprogname()); + cld80211_recv_msg(sock, cb); + } else if (events & POLLHUP) { + ALOGE("%s: Remote side hung up", getprogname()); + } else if (events & POLLIN) { + cld80211_recv_msg(sock, cb); + } else { + ALOGE("%s: Unknown event - %0x", getprogname(), events); + } +} + + +static int family_handler(struct nl_msg *msg, void *arg) +{ + struct family_data *res = arg; + struct nlattr *tb[CTRL_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *mcgrp; + int i; + + nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + if (!tb[CTRL_ATTR_MCAST_GROUPS]) + return NL_SKIP; + + nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) { + struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1]; + nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp), + nla_len(mcgrp), NULL); + + if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || + !tb2[CTRL_ATTR_MCAST_GRP_ID] || + strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]), + res->group, + nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0) + continue; + res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]); + break; + }; + + return NL_SKIP; +} + + +static int get_multicast_id(struct cld80211_ctx *ctx, const char *group) +{ + struct family_data res = { group, -ENOENT }; + struct nl_msg *nlmsg = nlmsg_alloc(); + + if (!nlmsg) { + return -1; + } + + genlmsg_put(nlmsg, 0, 0, ctx->nlctrl_familyid, 0, 0, + CTRL_CMD_GETFAMILY, 0); + nla_put_string(nlmsg, CTRL_ATTR_FAMILY_NAME, "cld80211"); + + cld80211_send_recv_msg(ctx, nlmsg, family_handler, &res); + ALOGI("%s: nlctrl family id: %d group: %s mcast_id: %d", getprogname(), + ctx->nlctrl_familyid, group, res.id); + nlmsg_free(nlmsg); + return res.id; +} + + +int cld80211_add_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup) +{ + if (!ctx || !mcgroup) { + ALOGE("%s: ctx/mcgroup is NULL: %s", getprogname(), __func__); + return 0; + } + int id = get_multicast_id(ctx, mcgroup); + if (id < 0) { + ALOGE("%s: Could not find group %s, errno: %d id: %d", + getprogname(), mcgroup, errno, id); + return id; + } + + int ret = nl_socket_add_membership(ctx->sock, id); + if (ret < 0) { + ALOGE("%s: Could not add membership to group %s, errno: %d", + getprogname(), mcgroup, errno); + } + + return ret; +} + + +int cld80211_remove_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup) +{ + // Drop membership is not a necessary cleanup action so comment it out. +#if 0 + if (!ctx || !mcgroup) { + ALOGE("%s: ctx/mcgroup is NULL: %s", getprogname(), __func__); + return 0; + } + int id = get_multicast_id(ctx, mcgroup); + if (id < 0) { + ALOGE("%s: Could not find group %s, errno: %d id: %d", + getprogname(), mcgroup, errno, id); + return id; + } + + int ret = nl_socket_drop_membership(ctx->sock, id); + if (ret < 0) { + ALOGE("%s: Could not drop membership from group %s, errno: %d," + " ret: %d", getprogname(), mcgroup, errno, ret); + return ret; + } +#endif + return 0; +} + + +struct nl_msg *cld80211_msg_alloc(struct cld80211_ctx *ctx, int cmd, + struct nlattr **nla_data, int pid) +{ + struct nl_msg *nlmsg; + + if (!ctx || !nla_data) { + ALOGE("%s: ctx is null: %s", getprogname(), __func__); + return NULL; + } + + nlmsg = nlmsg_alloc(); + if (nlmsg == NULL) { + ALOGE("%s: Out of memory", getprogname()); + return NULL; + } + + genlmsg_put(nlmsg, pid, /* seq = */ 0, ctx->netlink_familyid, + 0, 0, cmd, /* version = */ 0); + + *nla_data = nla_nest_start(nlmsg, CLD80211_ATTR_VENDOR_DATA); + if (!*nla_data) + goto cleanup; + + return nlmsg; + +cleanup: + if (nlmsg) + nlmsg_free(nlmsg); + return NULL; +} + + +int cld80211_send_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg) +{ + int err; + + if (!ctx || !ctx->sock || !nlmsg) { + ALOGE("%s: Invalid data from client", getprogname()); + return -EINVAL; + } + + err = nl_send_auto_complete(ctx->sock, nlmsg); /* send message */ + if (err < 0) { + ALOGE("%s: failed to send msg: %d", getprogname(), err); + return err; + } + + return 0; +} + + +int cld80211_send_recv_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data) +{ + int err; + + if (!ctx || !ctx->sock || !nlmsg) { + ALOGE("%s: Invalid data from client", getprogname()); + return -EINVAL; + } + + struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) + return -ENOMEM; + + err = nl_send_auto_complete(ctx->sock, nlmsg); /* send message */ + if (err < 0) + goto out; + + err = 1; + + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + + if (valid_handler) + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + valid_handler, valid_data); + else + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + response_handler, valid_data); + + while (err > 0) { /* wait for reply */ + int res = nl_recvmsgs(ctx->sock, cb); + if (res) { + ALOGE("%s: cld80211: nl_recvmsgs failed: %d", + getprogname(), res); + } + } +out: + nl_cb_put(cb); + return err; +} + + +int cld80211_recv(struct cld80211_ctx *ctx, int timeout, bool recv_multi_msg, + int (*valid_handler)(struct nl_msg *, void *), + void *cbctx) +{ + struct pollfd pfd[2]; + struct nl_cb *cb; + int err; + + if (!ctx || !ctx->sock || !valid_handler) { + ALOGE("%s: Invalid data from client", getprogname()); + return -EINVAL; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) + return -ENOMEM; + + memset(&pfd[0], 0, 2*sizeof(struct pollfd)); + + err = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, cbctx); + + pfd[0].fd = nl_socket_get_fd(ctx->sock); + pfd[0].events = POLLIN; + + pfd[1].fd = ctx->exit_sockets[1]; + pfd[1].events = POLLIN; + + do { + pfd[0].revents = 0; + pfd[1].revents = 0; + int result = poll(pfd, 2, timeout); + if (result < 0) { + ALOGE("%s: Error polling socket", getprogname()); + } else if (pfd[0].revents & (POLLIN | POLLHUP | POLLERR)) { + cld80211_handle_event(pfd[0].revents, ctx->sock, cb); + if (!recv_multi_msg) + break; + } else { + ALOGI("%s: Exiting poll", getprogname()); + break; + } + } while (1); + + nl_cb_put(cb); + return 0; +} + + +struct cld80211_ctx * cld80211_init(void) +{ + struct cld80211_ctx *ctx; + + ctx = (struct cld80211_ctx *)malloc(sizeof(struct cld80211_ctx)); + if (ctx == NULL) { + ALOGE("%s: Failed to alloc cld80211_ctx", getprogname()); + return NULL; + } + memset(ctx, 0, sizeof(struct cld80211_ctx)); + + ctx->sock = create_nl_socket(NETLINK_GENERIC); + if (ctx->sock == NULL) { + ALOGE("%s: Failed to create socket port", getprogname()); + goto cleanup; + } + + /* Set the socket buffer size */ + if (nl_socket_set_buffer_size(ctx->sock, SOCK_BUF_SIZE , 0) < 0) { + ALOGE("%s: Could not set nl_socket RX buffer size for sock: %s", + getprogname(), strerror(errno)); + /* continue anyway with the default (smaller) buffer */ + } + + ctx->netlink_familyid = genl_ctrl_resolve(ctx->sock, "cld80211"); + if (ctx->netlink_familyid < 0) { + ALOGE("%s: Could not resolve cld80211 familty id", + getprogname()); + goto cleanup; + } + + ctx->nlctrl_familyid = genl_ctrl_resolve(ctx->sock, "nlctrl"); + if (ctx->nlctrl_familyid < 0) { + ALOGE("%s: net link family nlctrl is not present: %d err:%d", + getprogname(), ctx->nlctrl_familyid, errno); + goto cleanup; + } + + + if (init_exit_sockets(ctx) != 0) { + ALOGE("%s: Failed to initialize exit sockets", getprogname()); + goto cleanup; + } + + return ctx; +cleanup: + if (ctx->sock) { + nl_socket_free(ctx->sock); + } + free (ctx); + return NULL; +} + + +void cld80211_deinit(struct cld80211_ctx *ctx) +{ + if (!ctx || !ctx->sock) { + ALOGE("%s: ctx/sock is NULL", getprogname()); + return; + } + nl_socket_free(ctx->sock); + cleanup_exit_sockets(ctx); + free (ctx); +} diff --git a/wcn6740/cld80211-lib/cld80211_lib.h b/wcn6740/cld80211-lib/cld80211_lib.h new file mode 100644 index 0000000..2503f2a --- /dev/null +++ b/wcn6740/cld80211-lib/cld80211_lib.h @@ -0,0 +1,157 @@ +/* Copyright (c) 2017, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + */ + +#ifndef CLD80211_LIB_H +#define CLD80211_LIB_H + +#ifdef __cplusplus +extern "C" { +#endif +#include <netlink/genl/genl.h> +#include <stdbool.h> + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +struct cld80211_ctx { + struct nl_sock *sock; + int netlink_familyid; + /* socket pair used to exit from blocking poll*/ + int exit_sockets[2]; + int sock_buf_size; + int nlctrl_familyid; +}; + +/** + * enum cld80211_attr - Driver/Application embeds the data in nlmsg with the + * help of below attributes + * CLD80211_ATTR_VENDOR_DATA: Embed all other attributes in this nested + * attribute. + * CLD80211_ATTR_DATA: Embed driver/application data in this attribute + * CLD80211_ATTR_META_DATA: Embed meta data for above data. This will help + * wlan driver to peek into request message packet without opening up definition + * of complete request message. + * @CLD80211_ATTR_CMD: cld80211 vendor subcommand in this attribute + * @CLD80211_ATTR_CMD_TAG_DATA: cld80211 vendor subcommand data is present in + * this attribute. It is a nested attribute with sub attributes of specified + * vendor sub command. + * + * Any new message in future can be added as another attribute + */ +enum cld80211_attr { + CLD80211_ATTR_VENDOR_DATA = 1, + CLD80211_ATTR_DATA, + CLD80211_ATTR_META_DATA, + CLD80211_ATTR_CMD, + CLD80211_ATTR_CMD_TAG_DATA, + + __CLD80211_ATTR_AFTER_LAST, + CLD80211_ATTR_MAX = __CLD80211_ATTR_AFTER_LAST - 1 +}; + +/** + * Create socket of type NETLINK_GENERIC + * Retuns valid sock only if socket creation is succesful and cld80211 + * family is present, returns NULL otherwise + */ +struct cld80211_ctx *cld80211_init(void); + +/** + * free the socket created in cld80211_init() + */ +void cld80211_deinit(struct cld80211_ctx *ctx); + +/** + * Allocate nl_msg and populate family and genl header details + */ +struct nl_msg *cld80211_msg_alloc(struct cld80211_ctx *ctx, int cmd, + struct nlattr **nla_data, int pid); + +/** + * Send nlmsg to driver and return; It doesn't wait for response + */ +int cld80211_send_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg); + +/** + * Send nlmsg to driver and get response, if any + */ +int cld80211_send_recv_msg(struct cld80211_ctx *ctx, struct nl_msg *nlmsg, + int (*valid_handler)(struct nl_msg *, void *), + void *valid_data); + +/** + * Add membership for multicast group "mcgroup" to receive the messages + * sent to this group from driver + */ +int cld80211_add_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup); + +/** + * Remove membership of multicast group "mcgroup" to stop receiving messages + * sent to this group from driver + */ +int cld80211_remove_mcast_group(struct cld80211_ctx *ctx, const char* mcgroup); + +/** + * Receive messages from driver on cld80211 family. Client can do + * a select()/poll() on the socket before calling this API. + * sock: nl_sock created for communication + * cb: nl callback context provided by client + * Returns corresponding errno when a failure happens while receiving nl msg + */ +int cld80211_recv_msg(struct nl_sock *sock, struct nl_cb *cb); + +/** + * Receive messages from driver on cld80211 family from the + * multicast groups subscribed + * timeout: Timeout in milliseconds for poll(); -1 is for infinite timeout. + * recv_multi_msg: Boolean flag to be sent false/true from client to indicate + * whether it wants to receive only one message or multiple + * messages from timeoutblock. + * false: Receive only one message and return + * true: Continue in the loop to receive multiple message till + * client explicitly sends exit via exit_cld80211_recv(). + * cbctx: Context provided by client, which is to be used when an + * nlmsg is received + * Returns corresponding errno when a failure happens while receiving nl msg + */ +int cld80211_recv(struct cld80211_ctx *ctx, int timeout, bool recv_multi_msg, + int (*valid_handler)(struct nl_msg *, void *), + void *cbctx); + +/** + * poll() is a blocking call on sock. Client has to unblock the poll() + * first to exit gracefully. + */ +void exit_cld80211_recv(struct cld80211_ctx *ctx); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wcn6740/cld80211-lib/configure.ac b/wcn6740/cld80211-lib/configure.ac new file mode 100644 index 0000000..7996d3f --- /dev/null +++ b/wcn6740/cld80211-lib/configure.ac @@ -0,0 +1,77 @@ +# -*- Autoconf -*- +# configure.ac -- Autoconf script for qcacld-tools +# + +AC_PREREQ(2.61) +AC_INIT([cld80211-lib], 1.0.0) +AM_INIT_AUTOMAKE([foreign]) +AM_MAINTAINER_MODE +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) +LT_INIT + +# 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 +PKG_PROG_PKG_CONFIG + +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]) + +has_libnl_ver=0 +# libnl-2 provides only libnl-2.0.pc file, so we check for separate libnl-genl-3.0.pc +# pkg-config file just for libnl-3.0 case. +# +PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0], [has_libnl_ver=3], [ + PKG_CHECK_MODULES([LIBNL], [libnl-2.0 >= 2.0], [has_libnl_ver=2], [ + PKG_CHECK_MODULES([LIBNL], [libnl-1], [has_libnl_ver=1], [has_libnl_ver=0])])]) + +if (test "$has_libnl_ver" -eq 0); then + AC_MSG_ERROR(libnl and libnl-genl are required but were not found) +fi + +if (test "$has_libnl_ver" -gt 1); then + AC_DEFINE([HAVE_LIBNL20], [1], [Define if you have libnl-2.0 or higher]) +fi + +if (test "$has_libnl_ver" -gt 2); then + AC_DEFINE([HAVE_LIBNL30], [1], [Define if you have libnl-3.0 or higher]) +fi + +AC_SUBST([LIBNL_CFLAGS]) +AC_SUBST([LIBNL_LIBS]) + +# 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 \ + cld80211-lib.pc +]) +AC_OUTPUT diff --git a/wcn6740/qcwcn/Android.mk b/wcn6740/qcwcn/Android.mk new file mode 100644 index 0000000..be3bb25 --- /dev/null +++ b/wcn6740/qcwcn/Android.mk @@ -0,0 +1,6 @@ +# adp8064 and fox box do not share wifi code +ifeq ($(filter adp8064 fox,$(TARGET_DEVICE)),) + ifeq ($(BOARD_WLAN_DEVICE),qcwcn) + include $(call all-subdir-makefiles) + endif +endif diff --git a/wcn6740/qcwcn/config/Android.mk b/wcn6740/qcwcn/config/Android.mk new file mode 100644 index 0000000..1c1622d --- /dev/null +++ b/wcn6740/qcwcn/config/Android.mk @@ -0,0 +1,24 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH := $(call my-dir) + +######################### + +WIFI_DRIVER_SOCKET_IFACE := wlan0 +ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_8_X) + include external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_conf.mk +endif +####################### diff --git a/wcn6740/qcwcn/wifi_hal/Android.mk b/wcn6740/qcwcn/wifi_hal/Android.mk new file mode 100644 index 0000000..bd9eb2b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/Android.mk @@ -0,0 +1,195 @@ +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +# Control APIs used by clients to communicate with HAL. +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -Wno-unused-parameter +LOCAL_CFLAGS += -Wall -Werror +LOCAL_MODULE := libwifi-hal-ctrl +LOCAL_VENDOR_MODULE := true +LOCAL_C_INCLUDES := $(LOCAL_PATH)/wifi_hal_ctrl +LOCAL_SRC_FILES := wifi_hal_ctrl/wifi_hal_ctrl.c +LOCAL_HEADER_LIBRARIES := libcutils_headers +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libwifi-hal-ctrl_headers +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/wifi_hal_ctrl +LOCAL_HEADER_LIBRARIES := libcutils_headers +include $(BUILD_HEADER_LIBRARY) + +# Make the HAL library +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -Wno-unused-parameter +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +LOCAL_CFLAGS += "-DLOG_NDEBUG=0" +endif + +ifneq ($(TARGET_USES_AOSP_FOR_WLAN), true) +LOCAL_CFLAGS += -DWCNSS_QTI_AOSP +endif + +# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true' +LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion + +LOCAL_CFLAGS += -Wall -Werror + +ifdef WIFI_DRIVER_STATE_CTRL_PARAM +LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\" +ifdef WIFI_DRIVER_STATE_ON +LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\" +endif +endif + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH) \ + external/libnl/include \ + $(call include-path-for, libhardware_legacy)/hardware_legacy \ + external/wpa_supplicant_8/src/drivers \ + $(TARGET_OUT_HEADERS)/cld80211-lib + +LOCAL_C_INCLUDES += \ + external/boringssl/include \ + external/boringssl/src/crypto/digest \ + external/boringssl/src/crypto/evp/ + +LOCAL_SRC_FILES := \ + list.cpp \ + wifi_hal.cpp \ + common.cpp \ + cpp_bindings.cpp \ + llstats.cpp \ + gscan.cpp \ + gscan_event_handler.cpp \ + rtt.cpp \ + ifaceeventhandler.cpp \ + tdls.cpp \ + nan.cpp \ + nan_ind.cpp \ + nan_req.cpp \ + nan_rsp.cpp \ + wificonfig.cpp \ + wifilogger.cpp \ + wifilogger_diag.cpp \ + ring_buffer.cpp \ + rb_wrapper.cpp \ + rssi_monitor.cpp \ + roam.cpp \ + radio_mode.cpp \ + tcp_params_update.cpp \ + wifihal_vendor.cpp + +LOCAL_MODULE := libwifi-hal-qcom +LOCAL_VENDOR_MODULE := true +LOCAL_CLANG := true +LOCAL_SHARED_LIBRARIES += libnetutils liblog libcld80211 +LOCAL_SHARED_LIBRARIES += libcrypto + +ifneq ($(wildcard external/libnl),) +LOCAL_SHARED_LIBRARIES += libnl +LOCAL_C_INCLUDES += external/libnl/include +else +LOCAL_SHARED_LIBRARIES += libnl_2 +LOCAL_C_INCLUDES += external/libnl-headers +endif + +LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers +LOCAL_SANITIZE := cfi signed-integer-overflow unsigned-integer-overflow + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_REQUIRED_MODULES := + +LOCAL_CFLAGS += -Wno-unused-parameter -Wall -Werror +LOCAL_CPPFLAGS += -Wno-conversion-null +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +LOCAL_CFLAGS += "-DLOG_NDEBUG=0" +endif + +# gscan.cpp: address of array 'cached_results[i].results' will always evaluate to 'true' +LOCAL_CLANG_CFLAGS := -Wno-pointer-bool-conversion + +ifdef WIFI_DRIVER_STATE_CTRL_PARAM +LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_CTRL_PARAM=\"$(WIFI_DRIVER_STATE_CTRL_PARAM)\" +ifdef WIFI_DRIVER_STATE_ON +LOCAL_CFLAGS += -DWIFI_DRIVER_STATE_ON=\"$(WIFI_DRIVER_STATE_ON)\" +endif +endif + +LOCAL_C_INCLUDES += \ + $(LOCAL_PATH) \ + external/libnl/include \ + $(call include-path-for, libhardware_legacy)/hardware_legacy \ + external/wpa_supplicant_8/src/drivers \ + $(TARGET_OUT_HEADERS)/cld80211-lib + +LOCAL_C_INCLUDES += \ + external/boringssl/include \ + external/boringssl/src/crypto/digest \ + external/boringssl/src/crypto/evp/ + +LOCAL_SRC_FILES := \ + list.cpp \ + wifi_hal.cpp \ + common.cpp \ + cpp_bindings.cpp \ + llstats.cpp \ + gscan.cpp \ + gscan_event_handler.cpp \ + rtt.cpp \ + ifaceeventhandler.cpp \ + tdls.cpp \ + nan.cpp \ + nan_ind.cpp \ + nan_req.cpp \ + nan_rsp.cpp \ + wificonfig.cpp \ + wifilogger.cpp \ + wifilogger_diag.cpp \ + ring_buffer.cpp \ + rb_wrapper.cpp \ + rssi_monitor.cpp \ + roam.cpp \ + radio_mode.cpp \ + tcp_params_update.cpp \ + wifihal_vendor.cpp + +LOCAL_CFLAGS += -Wall -Werror +LOCAL_MODULE := libwifi-hal-qcom +LOCAL_VENDOR_MODULE := true +LOCAL_CLANG := true +LOCAL_SHARED_LIBRARIES += libnetutils liblog +LOCAL_SHARED_LIBRARIES += libdl libcld80211 +LOCAL_SHARED_LIBRARIES += libwifi-hal-ctrl +LOCAL_SHARED_LIBRARIES += libcrypto + +ifneq ($(wildcard external/libnl),) +LOCAL_SHARED_LIBRARIES += libnl +LOCAL_C_INCLUDES += external/libnl/include +else +LOCAL_SHARED_LIBRARIES += libnl_2 +LOCAL_C_INCLUDES += external/libnl-headers +endif + +LOCAL_HEADER_LIBRARIES := libcutils_headers libutils_headers libwifi-hal-ctrl_headers libcld80211_headers +LOCAL_SANITIZE := cfi integer_overflow +include $(BUILD_SHARED_LIBRARY) diff --git a/wcn6740/qcwcn/wifi_hal/common.cpp b/wcn6740/qcwcn/wifi_hal/common.cpp new file mode 100644 index 0000000..263043b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/common.cpp @@ -0,0 +1,430 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> +#include <linux/pkt_sched.h> +#include <linux-private/linux/fib_rules.h> +#include <netlink/object-api.h> +#include <netlink-private/object-api.h> +#include <netlink-private/types.h> +#include <dlfcn.h> +#include <pthread.h> +#include "wifi_hal.h" +#include "common.h" +#include <errno.h> + +interface_info *getIfaceInfo(wifi_interface_handle handle) +{ + return (interface_info *)handle; +} + +wifi_handle getWifiHandle(wifi_interface_handle handle) +{ + return getIfaceInfo(handle)->handle; +} + +hal_info *getHalInfo(wifi_handle handle) +{ + return (hal_info *)handle; +} + +hal_info *getHalInfo(wifi_interface_handle handle) +{ + return getHalInfo(getWifiHandle(handle)); +} + +wifi_handle getWifiHandle(hal_info *info) +{ + return (wifi_handle)info; +} + +wifi_interface_handle getIfaceHandle(interface_info *info) +{ + return (wifi_interface_handle)info; +} + +wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg) +{ + hal_info *info = (hal_info *)handle; + + pthread_mutex_lock(&info->cb_lock); + + wifi_error result = WIFI_ERROR_OUT_OF_MEMORY; + + for (int i = 0; i < info->num_event_cb; i++) { + if(info->event_cb[i].nl_cmd == cmd && + info->event_cb[i].cb_arg == arg) { + info->event_cb[i].cb_func = func; + ALOGV("Updated event handler %p for nl_cmd 0x%0x" + " and arg %p", func, cmd, arg); + pthread_mutex_unlock(&info->cb_lock); + return WIFI_SUCCESS; + } + } + + if (info->num_event_cb < info->alloc_event_cb) { + info->event_cb[info->num_event_cb].nl_cmd = cmd; + info->event_cb[info->num_event_cb].vendor_id = 0; + info->event_cb[info->num_event_cb].vendor_subcmd = 0; + info->event_cb[info->num_event_cb].cb_func = func; + info->event_cb[info->num_event_cb].cb_arg = arg; + info->num_event_cb++; + ALOGV("Successfully added event handler %p for command %d", func, cmd); + result = WIFI_SUCCESS; + } else { + result = WIFI_ERROR_OUT_OF_MEMORY; + } + + pthread_mutex_unlock(&info->cb_lock); + return result; +} + +wifi_error wifi_register_vendor_handler(wifi_handle handle, + uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg) +{ + hal_info *info = (hal_info *)handle; + + pthread_mutex_lock(&info->cb_lock); + + wifi_error result = WIFI_ERROR_OUT_OF_MEMORY; + + for (int i = 0; i < info->num_event_cb; i++) { + if(info->event_cb[i].vendor_id == id && + info->event_cb[i].vendor_subcmd == subcmd) + { + info->event_cb[i].cb_func = func; + info->event_cb[i].cb_arg = arg; + ALOGV("Updated event handler %p for vendor 0x%0x, subcmd 0x%0x" + " and arg %p", func, id, subcmd, arg); + pthread_mutex_unlock(&info->cb_lock); + return WIFI_SUCCESS; + } + } + + if (info->num_event_cb < info->alloc_event_cb) { + info->event_cb[info->num_event_cb].nl_cmd = NL80211_CMD_VENDOR; + info->event_cb[info->num_event_cb].vendor_id = id; + info->event_cb[info->num_event_cb].vendor_subcmd = subcmd; + info->event_cb[info->num_event_cb].cb_func = func; + info->event_cb[info->num_event_cb].cb_arg = arg; + info->num_event_cb++; + ALOGV("Added event handler %p for vendor 0x%0x, subcmd 0x%0x and arg" + " %p", func, id, subcmd, arg); + result = WIFI_SUCCESS; + } else { + result = WIFI_ERROR_OUT_OF_MEMORY; + } + + pthread_mutex_unlock(&info->cb_lock); + return result; +} + +void wifi_unregister_handler(wifi_handle handle, int cmd) +{ + hal_info *info = (hal_info *)handle; + + if (cmd == NL80211_CMD_VENDOR) { + ALOGE("Must use wifi_unregister_vendor_handler to remove vendor handlers"); + return; + } + + pthread_mutex_lock(&info->cb_lock); + + for (int i = 0; i < info->num_event_cb; i++) { + if (info->event_cb[i].nl_cmd == cmd) { + if(i < info->num_event_cb-1) { + /* No need to memmove if only one entry exist and deleting + * the same, as the num_event_cb will become 0 in this case. + */ + memmove(&info->event_cb[i], &info->event_cb[i+1], + (info->num_event_cb - i) * sizeof(cb_info)); + } + info->num_event_cb--; + ALOGV("Successfully removed event handler for command %d", cmd); + break; + } + } + + pthread_mutex_unlock(&info->cb_lock); +} + +void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd) +{ + hal_info *info = (hal_info *)handle; + + pthread_mutex_lock(&info->cb_lock); + + for (int i = 0; i < info->num_event_cb; i++) { + + if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR + && info->event_cb[i].vendor_id == id + && info->event_cb[i].vendor_subcmd == subcmd) { + if(i < info->num_event_cb-1) { + /* No need to memmove if only one entry exist and deleting + * the same, as the num_event_cb will become 0 in this case. + */ + memmove(&info->event_cb[i], &info->event_cb[i+1], + (info->num_event_cb - i) * sizeof(cb_info)); + } + info->num_event_cb--; + ALOGV("Successfully removed event handler for vendor 0x%0x", id); + break; + } + } + + pthread_mutex_unlock(&info->cb_lock); +} + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +void hexdump(void *buf, u16 len) +{ + int i=0; + char *bytes = (char *)buf; + + if (len) { + ALOGV("******HexDump len:%d*********", len); + for (i = 0; ((i + 7) < len); i+=8) { + ALOGV("%02x %02x %02x %02x %02x %02x %02x %02x", + bytes[i], bytes[i+1], + bytes[i+2], bytes[i+3], + bytes[i+4], bytes[i+5], + bytes[i+6], bytes[i+7]); + } + if ((len - i) >= 4) { + ALOGV("%02x %02x %02x %02x", + bytes[i], bytes[i+1], + bytes[i+2], bytes[i+3]); + i+=4; + } + for (;i < len;i++) { + ALOGV("%02x", bytes[i]); + } + ALOGV("******HexDump End***********"); + } else { + return; + } +} + +/* Firmware sends RSSI value without noise floor. + * Add noise floor to the same and return absolute values. + */ +u8 get_rssi(u8 rssi_wo_noise_floor) +{ + return abs((int)rssi_wo_noise_floor - 96); +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +/* Pointer to the table of LOWI callback funcs */ +lowi_cb_table_t *LowiWifiHalApi = NULL; +/* LowiSupportedCapabilities read */ +u32 lowiSupportedCapabilities = 0; + +int compareLowiVersion(u16 major, u16 minor, u16 micro) +{ + u32 currVersion = 0x10000*(WIFIHAL_LOWI_MAJOR_VERSION) + \ + 0x100*(WIFIHAL_LOWI_MINOR_VERSION) + \ + WIFIHAL_LOWI_MICRO_VERSION; + + u32 lowiVersion = 0x10000*(major) + \ + 0x100*(minor) + \ + micro; + + return (memcmp(&currVersion, &lowiVersion, sizeof(u32))); +} + +/* + * This function will open the lowi shared library and obtain the + * Lowi Callback table and the capabilities supported. + * A version check is also performed in this function and if the version + * check fails then the callback table returned will be NULL. + */ +wifi_error fetchLowiCbTableAndCapabilities(lowi_cb_table_t **lowi_wifihal_api, + bool *lowi_get_capa_supported) +{ + getCbTable_t* lowiCbTable = NULL; + int ret = 0; + wifi_error retVal = WIFI_SUCCESS; + + *lowi_wifihal_api = NULL; + *lowi_get_capa_supported = false; + +#if __WORDSIZE == 64 + void* lowi_handle = dlopen("/vendor/lib64/liblowi_wifihal.so", RTLD_NOW); +#else + void* lowi_handle = dlopen("/vendor/lib/liblowi_wifihal.so", RTLD_NOW); +#endif + if (!lowi_handle) { + ALOGE("%s: NULL lowi_handle, err: %s", __FUNCTION__, dlerror()); + return WIFI_ERROR_UNKNOWN; + } + + lowiCbTable = (getCbTable_t*)dlsym(lowi_handle, + "lowi_wifihal_get_cb_table"); + if (!lowiCbTable) { + ALOGE("%s: NULL lowi callback table", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + *lowi_wifihal_api = lowiCbTable(); + + /* First check whether lowi module implements the get_lowi_version + * function. All the functions in lowi module starts with + * "lowi_wifihal_" prefix thus the below function name. + */ + if ((dlsym(lowi_handle, "lowi_wifihal_get_lowi_version") != NULL) && + ((*lowi_wifihal_api)->get_lowi_version != NULL)) { + u16 lowiMajorVersion = WIFIHAL_LOWI_MAJOR_VERSION; + u16 lowiMinorVersion = WIFIHAL_LOWI_MINOR_VERSION; + u16 lowiMicroVersion = WIFIHAL_LOWI_MICRO_VERSION; + int versionCheck = -1; + + ret = (*lowi_wifihal_api)->get_lowi_version(&lowiMajorVersion, + &lowiMinorVersion, + &lowiMicroVersion); + if (ret) { + ALOGE("%s: get_lowi_version returned error:%d", + __FUNCTION__, ret); + retVal = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + ALOGV("%s: Lowi version:%d.%d.%d", __FUNCTION__, + lowiMajorVersion, lowiMinorVersion, + lowiMicroVersion); + + /* Compare the version with version in wifihal_internal.h */ + versionCheck = compareLowiVersion(lowiMajorVersion, + lowiMinorVersion, + lowiMicroVersion); + if (versionCheck < 0) { + ALOGE("%s: Version Check failed:%d", __FUNCTION__, + versionCheck); + retVal = WIFI_ERROR_NOT_SUPPORTED; + goto cleanup; + } + } + else { + ALOGV("%s: lowi_wifihal_get_lowi_version not present", + __FUNCTION__); + } + + + /* Check if get_lowi_capabilities func pointer exists in + * the lowi lib and populate lowi_get_capa_supported + * All the functions in lowi modules starts with + * "lowi_wifihal_ prefix" thus the below function name. + */ + if (dlsym(lowi_handle, "lowi_wifihal_get_lowi_capabilities") != NULL) { + *lowi_get_capa_supported = true; + } + else { + ALOGV("lowi_wifihal_get_lowi_capabilities() is not supported."); + *lowi_get_capa_supported = false; + } +cleanup: + if (retVal) { + *lowi_wifihal_api = NULL; + } + return retVal; +} + +lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities) +{ + int ret = WIFI_SUCCESS; + bool lowi_get_capabilities_support = false; + + if (LowiWifiHalApi == NULL) { + ALOGV("%s: LowiWifiHalApi Null, Initialize Lowi", + __FUNCTION__); + ret = fetchLowiCbTableAndCapabilities(&LowiWifiHalApi, + &lowi_get_capabilities_support); + if (ret != WIFI_SUCCESS || LowiWifiHalApi == NULL || + LowiWifiHalApi->init == NULL) { + ALOGE("%s: LOWI is not supported.", __FUNCTION__); + goto cleanup; + } + /* Initialize LOWI if it isn't up already. */ + ret = LowiWifiHalApi->init(); + if (ret) { + ALOGE("%s: failed lowi initialization. " + "Returned error:%d. Exit.", __FUNCTION__, ret); + goto cleanup; + } + if (!lowi_get_capabilities_support || + LowiWifiHalApi->get_lowi_capabilities == NULL) { + ALOGV("%s: Allow rtt APIs thru LOWI to proceed even though " + "get_lowi_capabilities() is not supported. Returning", + __FUNCTION__); + lowiSupportedCapabilities |= + (ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + return LowiWifiHalApi; + } + ret = + LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities); + if (ret) { + ALOGV("%s: failed to get lowi supported capabilities." + "Returned error:%d. Exit.", __FUNCTION__, ret); + goto cleanup; + } + } else if (lowiSupportedCapabilities == 0 && + LowiWifiHalApi->get_lowi_capabilities) { + LowiWifiHalApi->get_lowi_capabilities(&lowiSupportedCapabilities); + } + + if ((lowiSupportedCapabilities & requested_lowi_capabilities) == 0) { + return NULL; + } + return LowiWifiHalApi; + +cleanup: + if (LowiWifiHalApi && LowiWifiHalApi->destroy) { + ret = LowiWifiHalApi->destroy(); + } + LowiWifiHalApi = NULL; + lowiSupportedCapabilities = 0; + return LowiWifiHalApi; +} + +wifi_error mapKernelErrortoWifiHalError(int kern_err) +{ + if (kern_err >= 0) + return WIFI_SUCCESS; + + switch (kern_err) { + case -EOPNOTSUPP: + return WIFI_ERROR_NOT_SUPPORTED; + case -EAGAIN: + return WIFI_ERROR_NOT_AVAILABLE; + case -EINVAL: + return WIFI_ERROR_INVALID_ARGS; + case -ETIMEDOUT: + return WIFI_ERROR_TIMED_OUT; + case -ENOMEM: + return WIFI_ERROR_OUT_OF_MEMORY; + case -EBUSY: + return WIFI_ERROR_BUSY; + case -ENOBUFS: + return WIFI_ERROR_TOO_MANY_REQUESTS; + } + return WIFI_ERROR_UNKNOWN; +} diff --git a/wcn6740/qcwcn/wifi_hal/common.h b/wcn6740/qcwcn/wifi_hal/common.h new file mode 100644 index 0000000..a48605a --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/common.h @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "wifi_hal.h" + +#ifndef __WIFI_HAL_COMMON_H__ +#define __WIFI_HAL_COMMON_H__ + +#ifndef LOG_TAG +#define LOG_TAG "WifiHAL" +#endif + +#include <stdint.h> +#include <fcntl.h> +#include <inttypes.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> + +#include "nl80211_copy.h" + +#include <utils/Log.h> +#include "rb_wrapper.h" +#include "pkt_stats.h" +#include "wifihal_internal.h" +#include "qca-vendor_copy.h" + +#define SOCKET_BUFFER_SIZE (32768U) +#define RECV_BUF_SIZE (4096) +#define DEFAULT_EVENT_CB_SIZE (64) +#define NUM_RING_BUFS 5 +#define MAX_NUM_RADAR_HISTORY 64 + +#define WIFI_HAL_CTRL_IFACE "/dev/socket/wifihal/wifihal_ctrlsock" + +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#ifndef BIT +#define BIT(x) (1 << (x)) +#endif + +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events); + +class WifiCommand; + +typedef struct { + int nl_cmd; + uint32_t vendor_id; + int vendor_subcmd; + nl_recvmsg_msg_cb_t cb_func; + void *cb_arg; +} cb_info; + +typedef struct { + wifi_request_id id; + WifiCommand *cmd; +} cmd_info; + +typedef struct { + wifi_handle handle; // handle to wifi data + char name[IFNAMSIZ+1]; // interface name + trailing null + int id; // id to use when talking to driver +} interface_info; + +typedef struct { + wifi_gscan_capabilities gscan_capa; + wifi_roaming_capabilities roaming_capa; +} wifi_capa; + +typedef struct { + u8 *flags; + size_t flags_len; +} features_info; + +enum pkt_log_version { + PKT_LOG_V0 = 0, // UNSPECIFIED Target + PKT_LOG_V1 = 1, // ROME Base Target + PKT_LOG_V2 = 2, // HELIUM Base Target + PKT_LOG_V3 = 3, // LETHIUM Base target +}; + +struct gscan_event_handlers_s; +struct rssi_monitor_event_handler_s; +struct cld80211_ctx; + +struct ctrl_sock { + int s; + struct sockaddr_un local; +}; + +typedef struct hal_info_s { + + struct nl_sock *cmd_sock; // command socket object + struct nl_sock *event_sock; // event socket object + struct nl_sock *user_sock; // user socket object + struct ctrl_sock wifihal_ctrl_sock; // ctrl sock object + struct list_head monitor_sockets; // list of monitor sockets + int nl80211_family_id; // family id for 80211 driver + + bool in_event_loop; // Indicates that event loop is active + bool clean_up; // Indication to clean up the socket + + wifi_internal_event_handler event_handler; // default event handler + wifi_cleaned_up_handler cleaned_up_handler; // socket cleaned up handler + + cb_info *event_cb; // event callbacks + int num_event_cb; // number of event callbacks + int alloc_event_cb; // number of allocated callback objects + pthread_mutex_t cb_lock; // mutex for the event_cb access + + interface_info **interfaces; // array of interfaces + int num_interfaces; // number of interfaces + + feature_set supported_feature_set; + /* driver supported features defined by enum qca_wlan_vendor_features that + can be queried by vendor command QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ + features_info driver_supported_features; + u32 supported_logger_feature_set; + // add other details + int user_sock_arg; + int event_sock_arg; + struct rb_info rb_infos[NUM_RING_BUFS]; + void (*on_ring_buffer_data) (char *ring_name, char *buffer, int buffer_size, + wifi_ring_buffer_status *status); + void (*on_alert) (wifi_request_id id, char *buffer, int buffer_size, int err_code); + struct pkt_stats_s *pkt_stats; + + /* socket pair used to exit from blocking poll*/ + int exit_sockets[2]; + u32 rx_buf_size_allocated; + u32 rx_buf_size_occupied; + wifi_ring_buffer_entry *rx_aggr_pkts; + rx_aggr_stats aggr_stats; + u32 prev_seq_no; + // pointer to structure having various gscan_event_handlers + struct gscan_event_handlers_s *gscan_handlers; + struct tcp_param_cmd_handler_s *tcp_param_handler; + /* mutex for the log_handler access*/ + pthread_mutex_t lh_lock; + /* mutex for the alert_handler access*/ + pthread_mutex_t ah_lock; + u32 firmware_bus_max_size; + bool fate_monitoring_enabled; + packet_fate_monitor_info *pkt_fate_stats; + /* mutex for the packet fate stats shared resource protection */ + pthread_mutex_t pkt_fate_stats_lock; + struct rssi_monitor_event_handler_s *rssi_handlers; + struct radio_event_handler_s *radio_handlers; + wifi_capa capa; + struct cld80211_ctx *cldctx; + bool apf_enabled; + bool support_nan_ext_cmd; + pkt_log_version pkt_log_ver; +} hal_info; + +typedef struct { + bool radar_detected; + u32 freq; + u64 clock_boottime; +} radar_history_result; + +static inline void wifi_put_le16(u8 *a, u16 val) { + a[1] = val >> 8; + a[0] = val & 0xff; +} + +wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg); +wifi_error wifi_register_vendor_handler(wifi_handle handle, + uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg); + +void wifi_unregister_handler(wifi_handle handle, int cmd); +void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd); + +interface_info *getIfaceInfo(wifi_interface_handle); +wifi_handle getWifiHandle(wifi_interface_handle handle); +hal_info *getHalInfo(wifi_handle handle); +hal_info *getHalInfo(wifi_interface_handle handle); +wifi_handle getWifiHandle(hal_info *info); +wifi_interface_handle getIfaceHandle(interface_info *info); +wifi_error initializeGscanHandlers(hal_info *info); +wifi_error cleanupGscanHandlers(hal_info *info); +wifi_error initializeRSSIMonitorHandler(hal_info *info); +wifi_error cleanupRSSIMonitorHandler(hal_info *info); +wifi_error initializeRadioHandler(hal_info *info); +wifi_error cleanupRadioHandler(hal_info *info); + +lowi_cb_table_t *getLowiCallbackTable(u32 requested_lowi_capabilities); + +wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, + wifi_interface_handle iface, u8 *ip_packet, u16 ip_packet_len, + u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec); +wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, + wifi_interface_handle iface); +wifi_error wifi_start_rssi_monitoring(wifi_request_id id, wifi_interface_handle + iface, s8 max_rssi, s8 min_rssi, wifi_rssi_event_handler eh); +wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, wifi_interface_handle iface); +wifi_error wifi_set_radio_mode_change_handler(wifi_request_id id, wifi_interface_handle + iface, wifi_radio_mode_change_handler eh); +wifi_error mapKernelErrortoWifiHalError(int kern_err); +void wifi_cleanup_dynamic_ifaces(wifi_handle handle); +wifi_error wifi_virtual_interface_create(wifi_handle handle, const char* ifname, + wifi_interface_type iface_type); +wifi_error wifi_virtual_interface_delete(wifi_handle handle, const char* ifname); +wifi_error wifi_get_radar_history(wifi_interface_handle handle, + radar_history_result *resultBuf, int resultBufSize, int *numResults); +wifi_error wifi_disable_next_cac(wifi_interface_handle handle); +// some common macros + +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) + +#define REQUEST_ID_MAX 1000 +#define REQUEST_ID_U8_MAX 255 +#define get_requestid() ((arc4random()%REQUEST_ID_MAX) + 1) +#define get_requestid_u8() ((arc4random()%REQUEST_ID_U8_MAX) + 1) +#define WAIT_TIME_FOR_SET_REG_DOMAIN 50000 + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ +void hexdump(void *bytes, u16 len); +u8 get_rssi(u8 rssi_wo_noise_floor); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp b/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp new file mode 100644 index 0000000..4ac01b7 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp @@ -0,0 +1,1029 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Not a Contribution + */ + +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <net/if.h> + +#include "nl80211_copy.h" +#include <ctype.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "vendor_definitions.h" + +void appendFmt(char *buf, size_t buf_len, int &offset, const char *fmt, ...) +{ + va_list params; + va_start(params, fmt); + offset += vsnprintf(buf + offset, buf_len - offset, fmt, params); + va_end(params); +} + +#define C2S(x) case x: return #x; + +static const char *cmdToString(int cmd) +{ + switch (cmd) { + C2S(NL80211_CMD_UNSPEC) + C2S(NL80211_CMD_GET_WIPHY) + C2S(NL80211_CMD_SET_WIPHY) + C2S(NL80211_CMD_NEW_WIPHY) + C2S(NL80211_CMD_DEL_WIPHY) + C2S(NL80211_CMD_GET_INTERFACE) + C2S(NL80211_CMD_SET_INTERFACE) + C2S(NL80211_CMD_NEW_INTERFACE) + C2S(NL80211_CMD_DEL_INTERFACE) + C2S(NL80211_CMD_GET_KEY) + C2S(NL80211_CMD_SET_KEY) + C2S(NL80211_CMD_NEW_KEY) + C2S(NL80211_CMD_DEL_KEY) + C2S(NL80211_CMD_GET_BEACON) + C2S(NL80211_CMD_SET_BEACON) + C2S(NL80211_CMD_START_AP) + C2S(NL80211_CMD_STOP_AP) + C2S(NL80211_CMD_GET_STATION) + C2S(NL80211_CMD_SET_STATION) + C2S(NL80211_CMD_NEW_STATION) + C2S(NL80211_CMD_DEL_STATION) + C2S(NL80211_CMD_GET_MPATH) + C2S(NL80211_CMD_SET_MPATH) + C2S(NL80211_CMD_NEW_MPATH) + C2S(NL80211_CMD_DEL_MPATH) + C2S(NL80211_CMD_SET_BSS) + C2S(NL80211_CMD_SET_REG) + C2S(NL80211_CMD_REQ_SET_REG) + C2S(NL80211_CMD_GET_MESH_CONFIG) + C2S(NL80211_CMD_SET_MESH_CONFIG) + C2S(NL80211_CMD_SET_MGMT_EXTRA_IE) + C2S(NL80211_CMD_GET_REG) + C2S(NL80211_CMD_GET_SCAN) + C2S(NL80211_CMD_TRIGGER_SCAN) + C2S(NL80211_CMD_NEW_SCAN_RESULTS) + C2S(NL80211_CMD_SCAN_ABORTED) + C2S(NL80211_CMD_REG_CHANGE) + C2S(NL80211_CMD_AUTHENTICATE) + C2S(NL80211_CMD_ASSOCIATE) + C2S(NL80211_CMD_DEAUTHENTICATE) + C2S(NL80211_CMD_DISASSOCIATE) + C2S(NL80211_CMD_MICHAEL_MIC_FAILURE) + C2S(NL80211_CMD_REG_BEACON_HINT) + C2S(NL80211_CMD_JOIN_IBSS) + C2S(NL80211_CMD_LEAVE_IBSS) + C2S(NL80211_CMD_TESTMODE) + C2S(NL80211_CMD_CONNECT) + C2S(NL80211_CMD_ROAM) + C2S(NL80211_CMD_DISCONNECT) + C2S(NL80211_CMD_SET_WIPHY_NETNS) + C2S(NL80211_CMD_GET_SURVEY) + C2S(NL80211_CMD_NEW_SURVEY_RESULTS) + C2S(NL80211_CMD_SET_PMKSA) + C2S(NL80211_CMD_DEL_PMKSA) + C2S(NL80211_CMD_FLUSH_PMKSA) + C2S(NL80211_CMD_REMAIN_ON_CHANNEL) + C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL) + C2S(NL80211_CMD_SET_TX_BITRATE_MASK) + C2S(NL80211_CMD_REGISTER_FRAME) + C2S(NL80211_CMD_FRAME) + C2S(NL80211_CMD_FRAME_TX_STATUS) + C2S(NL80211_CMD_SET_POWER_SAVE) + C2S(NL80211_CMD_GET_POWER_SAVE) + C2S(NL80211_CMD_SET_CQM) + C2S(NL80211_CMD_NOTIFY_CQM) + C2S(NL80211_CMD_SET_CHANNEL) + C2S(NL80211_CMD_SET_WDS_PEER) + C2S(NL80211_CMD_FRAME_WAIT_CANCEL) + C2S(NL80211_CMD_JOIN_MESH) + C2S(NL80211_CMD_LEAVE_MESH) + C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE) + C2S(NL80211_CMD_UNPROT_DISASSOCIATE) + C2S(NL80211_CMD_NEW_PEER_CANDIDATE) + C2S(NL80211_CMD_GET_WOWLAN) + C2S(NL80211_CMD_SET_WOWLAN) + C2S(NL80211_CMD_START_SCHED_SCAN) + C2S(NL80211_CMD_STOP_SCHED_SCAN) + C2S(NL80211_CMD_SCHED_SCAN_RESULTS) + C2S(NL80211_CMD_SCHED_SCAN_STOPPED) + C2S(NL80211_CMD_SET_REKEY_OFFLOAD) + C2S(NL80211_CMD_PMKSA_CANDIDATE) + C2S(NL80211_CMD_TDLS_OPER) + C2S(NL80211_CMD_TDLS_MGMT) + C2S(NL80211_CMD_UNEXPECTED_FRAME) + C2S(NL80211_CMD_PROBE_CLIENT) + C2S(NL80211_CMD_REGISTER_BEACONS) + C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME) + C2S(NL80211_CMD_SET_NOACK_MAP) + C2S(NL80211_CMD_CH_SWITCH_NOTIFY) + C2S(NL80211_CMD_START_P2P_DEVICE) + C2S(NL80211_CMD_STOP_P2P_DEVICE) + C2S(NL80211_CMD_CONN_FAILED) + C2S(NL80211_CMD_SET_MCAST_RATE) + C2S(NL80211_CMD_SET_MAC_ACL) + C2S(NL80211_CMD_RADAR_DETECT) + C2S(NL80211_CMD_GET_PROTOCOL_FEATURES) + C2S(NL80211_CMD_UPDATE_FT_IES) + C2S(NL80211_CMD_FT_EVENT) + C2S(NL80211_CMD_CRIT_PROTOCOL_START) + C2S(NL80211_CMD_CRIT_PROTOCOL_STOP) + C2S(NL80211_CMD_GET_COALESCE) + C2S(NL80211_CMD_SET_COALESCE) + C2S(NL80211_CMD_CHANNEL_SWITCH) + C2S(NL80211_CMD_VENDOR) + C2S(NL80211_CMD_SET_QOS_MAP) + default: + return "NL80211_CMD_UNKNOWN"; + } +} + +const char *attributeToString(int attribute) +{ + switch (attribute) { + C2S(NL80211_ATTR_UNSPEC) + + C2S(NL80211_ATTR_WIPHY) + C2S(NL80211_ATTR_WIPHY_NAME) + + C2S(NL80211_ATTR_IFINDEX) + C2S(NL80211_ATTR_IFNAME) + C2S(NL80211_ATTR_IFTYPE) + + C2S(NL80211_ATTR_MAC) + + C2S(NL80211_ATTR_KEY_DATA) + C2S(NL80211_ATTR_KEY_IDX) + C2S(NL80211_ATTR_KEY_CIPHER) + C2S(NL80211_ATTR_KEY_SEQ) + C2S(NL80211_ATTR_KEY_DEFAULT) + + C2S(NL80211_ATTR_BEACON_INTERVAL) + C2S(NL80211_ATTR_DTIM_PERIOD) + C2S(NL80211_ATTR_BEACON_HEAD) + C2S(NL80211_ATTR_BEACON_TAIL) + + C2S(NL80211_ATTR_STA_AID) + C2S(NL80211_ATTR_STA_FLAGS) + C2S(NL80211_ATTR_STA_LISTEN_INTERVAL) + C2S(NL80211_ATTR_STA_SUPPORTED_RATES) + C2S(NL80211_ATTR_STA_VLAN) + C2S(NL80211_ATTR_STA_INFO) + + C2S(NL80211_ATTR_WIPHY_BANDS) + + C2S(NL80211_ATTR_MNTR_FLAGS) + + C2S(NL80211_ATTR_MESH_ID) + C2S(NL80211_ATTR_STA_PLINK_ACTION) + C2S(NL80211_ATTR_MPATH_NEXT_HOP) + C2S(NL80211_ATTR_MPATH_INFO) + + C2S(NL80211_ATTR_BSS_CTS_PROT) + C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE) + C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME) + + C2S(NL80211_ATTR_HT_CAPABILITY) + + C2S(NL80211_ATTR_SUPPORTED_IFTYPES) + + C2S(NL80211_ATTR_REG_ALPHA2) + C2S(NL80211_ATTR_REG_RULES) + + C2S(NL80211_ATTR_MESH_CONFIG) + + C2S(NL80211_ATTR_BSS_BASIC_RATES) + + C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS) + C2S(NL80211_ATTR_WIPHY_FREQ) + C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE) + + C2S(NL80211_ATTR_KEY_DEFAULT_MGMT) + + C2S(NL80211_ATTR_MGMT_SUBTYPE) + C2S(NL80211_ATTR_IE) + + C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS) + + C2S(NL80211_ATTR_SCAN_FREQUENCIES) + C2S(NL80211_ATTR_SCAN_SSIDS) + C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */ + C2S(NL80211_ATTR_BSS) + + C2S(NL80211_ATTR_REG_INITIATOR) + C2S(NL80211_ATTR_REG_TYPE) + + C2S(NL80211_ATTR_SUPPORTED_COMMANDS) + + C2S(NL80211_ATTR_FRAME) + C2S(NL80211_ATTR_SSID) + C2S(NL80211_ATTR_AUTH_TYPE) + C2S(NL80211_ATTR_REASON_CODE) + + C2S(NL80211_ATTR_KEY_TYPE) + + C2S(NL80211_ATTR_MAX_SCAN_IE_LEN) + C2S(NL80211_ATTR_CIPHER_SUITES) + + C2S(NL80211_ATTR_FREQ_BEFORE) + C2S(NL80211_ATTR_FREQ_AFTER) + + C2S(NL80211_ATTR_FREQ_FIXED) + + + C2S(NL80211_ATTR_WIPHY_RETRY_SHORT) + C2S(NL80211_ATTR_WIPHY_RETRY_LONG) + C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD) + C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD) + + C2S(NL80211_ATTR_TIMED_OUT) + + C2S(NL80211_ATTR_USE_MFP) + + C2S(NL80211_ATTR_STA_FLAGS2) + + C2S(NL80211_ATTR_CONTROL_PORT) + + C2S(NL80211_ATTR_TESTDATA) + + C2S(NL80211_ATTR_PRIVACY) + + C2S(NL80211_ATTR_DISCONNECTED_BY_AP) + C2S(NL80211_ATTR_STATUS_CODE) + + C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE) + C2S(NL80211_ATTR_CIPHER_SUITE_GROUP) + C2S(NL80211_ATTR_WPA_VERSIONS) + C2S(NL80211_ATTR_AKM_SUITES) + + C2S(NL80211_ATTR_REQ_IE) + C2S(NL80211_ATTR_RESP_IE) + + C2S(NL80211_ATTR_PREV_BSSID) + + C2S(NL80211_ATTR_KEY) + C2S(NL80211_ATTR_KEYS) + + C2S(NL80211_ATTR_PID) + + C2S(NL80211_ATTR_4ADDR) + + C2S(NL80211_ATTR_SURVEY_INFO) + + C2S(NL80211_ATTR_PMKID) + C2S(NL80211_ATTR_MAX_NUM_PMKIDS) + + C2S(NL80211_ATTR_DURATION) + + C2S(NL80211_ATTR_COOKIE) + + C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS) + + C2S(NL80211_ATTR_TX_RATES) + + C2S(NL80211_ATTR_FRAME_MATCH) + + C2S(NL80211_ATTR_ACK) + + C2S(NL80211_ATTR_PS_STATE) + + C2S(NL80211_ATTR_CQM) + + C2S(NL80211_ATTR_LOCAL_STATE_CHANGE) + + C2S(NL80211_ATTR_AP_ISOLATE) + + C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING) + C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL) + + C2S(NL80211_ATTR_TX_FRAME_TYPES) + C2S(NL80211_ATTR_RX_FRAME_TYPES) + C2S(NL80211_ATTR_FRAME_TYPE) + + C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE) + C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT) + + C2S(NL80211_ATTR_SUPPORT_IBSS_RSN) + + C2S(NL80211_ATTR_WIPHY_ANTENNA_TX) + C2S(NL80211_ATTR_WIPHY_ANTENNA_RX) + + C2S(NL80211_ATTR_MCAST_RATE) + + C2S(NL80211_ATTR_OFFCHANNEL_TX_OK) + + C2S(NL80211_ATTR_BSS_HT_OPMODE) + + C2S(NL80211_ATTR_KEY_DEFAULT_TYPES) + + C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION) + + C2S(NL80211_ATTR_MESH_SETUP) + + C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX) + C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX) + + C2S(NL80211_ATTR_SUPPORT_MESH_AUTH) + C2S(NL80211_ATTR_STA_PLINK_STATE) + + C2S(NL80211_ATTR_WOWLAN_TRIGGERS) + C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED) + + C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL) + + C2S(NL80211_ATTR_INTERFACE_COMBINATIONS) + C2S(NL80211_ATTR_SOFTWARE_IFTYPES) + + C2S(NL80211_ATTR_REKEY_DATA) + + C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS) + C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN) + + C2S(NL80211_ATTR_SCAN_SUPP_RATES) + + C2S(NL80211_ATTR_HIDDEN_SSID) + + C2S(NL80211_ATTR_IE_PROBE_RESP) + C2S(NL80211_ATTR_IE_ASSOC_RESP) + + C2S(NL80211_ATTR_STA_WME) + C2S(NL80211_ATTR_SUPPORT_AP_UAPSD) + + C2S(NL80211_ATTR_ROAM_SUPPORT) + + C2S(NL80211_ATTR_SCHED_SCAN_MATCH) + C2S(NL80211_ATTR_MAX_MATCH_SETS) + + C2S(NL80211_ATTR_PMKSA_CANDIDATE) + + C2S(NL80211_ATTR_TX_NO_CCK_RATE) + + C2S(NL80211_ATTR_TDLS_ACTION) + C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN) + C2S(NL80211_ATTR_TDLS_OPERATION) + C2S(NL80211_ATTR_TDLS_SUPPORT) + C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP) + + C2S(NL80211_ATTR_DEVICE_AP_SME) + + C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK) + + C2S(NL80211_ATTR_FEATURE_FLAGS) + + C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD) + + C2S(NL80211_ATTR_PROBE_RESP) + + C2S(NL80211_ATTR_DFS_REGION) + + C2S(NL80211_ATTR_DISABLE_HT) + C2S(NL80211_ATTR_HT_CAPABILITY_MASK) + + C2S(NL80211_ATTR_NOACK_MAP) + + C2S(NL80211_ATTR_INACTIVITY_TIMEOUT) + + C2S(NL80211_ATTR_RX_SIGNAL_DBM) + + C2S(NL80211_ATTR_BG_SCAN_PERIOD) + + C2S(NL80211_ATTR_WDEV) + + C2S(NL80211_ATTR_USER_REG_HINT_TYPE) + + C2S(NL80211_ATTR_CONN_FAILED_REASON) + + C2S(NL80211_ATTR_SAE_DATA) + + C2S(NL80211_ATTR_VHT_CAPABILITY) + + C2S(NL80211_ATTR_SCAN_FLAGS) + + C2S(NL80211_ATTR_CHANNEL_WIDTH) + C2S(NL80211_ATTR_CENTER_FREQ1) + C2S(NL80211_ATTR_CENTER_FREQ2) + + C2S(NL80211_ATTR_P2P_CTWINDOW) + C2S(NL80211_ATTR_P2P_OPPPS) + + C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE) + + C2S(NL80211_ATTR_ACL_POLICY) + + C2S(NL80211_ATTR_MAC_ADDRS) + + C2S(NL80211_ATTR_MAC_ACL_MAX) + + C2S(NL80211_ATTR_RADAR_EVENT) + + C2S(NL80211_ATTR_EXT_CAPA) + C2S(NL80211_ATTR_EXT_CAPA_MASK) + + C2S(NL80211_ATTR_STA_CAPABILITY) + C2S(NL80211_ATTR_STA_EXT_CAPABILITY) + + C2S(NL80211_ATTR_PROTOCOL_FEATURES) + C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP) + + C2S(NL80211_ATTR_DISABLE_VHT) + C2S(NL80211_ATTR_VHT_CAPABILITY_MASK) + + C2S(NL80211_ATTR_MDID) + C2S(NL80211_ATTR_IE_RIC) + + C2S(NL80211_ATTR_CRIT_PROT_ID) + C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION) + + C2S(NL80211_ATTR_PEER_AID) + + C2S(NL80211_ATTR_COALESCE_RULE) + + C2S(NL80211_ATTR_CH_SWITCH_COUNT) + C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX) + C2S(NL80211_ATTR_CSA_IES) + C2S(NL80211_ATTR_CSA_C_OFF_BEACON) + C2S(NL80211_ATTR_CSA_C_OFF_PRESP) + + C2S(NL80211_ATTR_RXMGMT_FLAGS) + + C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS) + + C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES) + + C2S(NL80211_ATTR_HANDLE_DFS) + + C2S(NL80211_ATTR_SUPPORT_5_MHZ) + C2S(NL80211_ATTR_SUPPORT_10_MHZ) + + C2S(NL80211_ATTR_OPMODE_NOTIF) + + C2S(NL80211_ATTR_VENDOR_ID) + C2S(NL80211_ATTR_VENDOR_SUBCMD) + C2S(NL80211_ATTR_VENDOR_DATA) + C2S(NL80211_ATTR_VENDOR_EVENTS) + + C2S(NL80211_ATTR_QOS_MAP) + default: + return "NL80211_ATTR_UNKNOWN"; + } +} + +void WifiEvent::log() { + parse(); + + byte *data = (byte *)genlmsg_attrdata(mHeader, 0); + int len = genlmsg_attrlen(mHeader, 0); + + for (int i = 0; i < len; i += 16) { + char line[81]; + int linelen = min(16, len - i); + int offset = 0; + appendFmt(line, sizeof(line), offset, "%02x", data[i]); + for (int j = 1; j < linelen; j++) { + appendFmt(line, sizeof(line), offset, " %02x", data[i+j]); + } + + for (int j = linelen; j < 16; j++) { + appendFmt(line, sizeof(line), offset, " "); + } + + line[23] = '-'; + + appendFmt(line, sizeof(line), offset, " "); + + for (int j = 0; j < linelen; j++) { + if (isprint(data[i+j])) { + appendFmt(line, sizeof(line), offset, "%c", data[i+j]); + } else { + appendFmt(line, sizeof(line), offset, "-"); + } + } + + } + +} + +const char *WifiEvent::get_cmdString() { + return cmdToString(get_cmd()); +} + + +int WifiEvent::parse() { + if (mHeader != NULL) { + return WIFI_SUCCESS; + } + mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg)); + int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0), + genlmsg_attrlen(mHeader, 0), NULL); + + return result; +} + +wifi_error WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) { + + destroy(); + + mMsg = nlmsg_alloc(); + if (mMsg != NULL) { + genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family, + hdrlen, flags, cmd, /* version = */ 0); + return WIFI_SUCCESS; + } else { + return WIFI_ERROR_OUT_OF_MEMORY; + } +} + +wifi_error WifiRequest::create(uint32_t id, int subcmd) { + wifi_error res = create(NL80211_CMD_VENDOR); + if (res != WIFI_SUCCESS) + return res; + + res = put_u32(NL80211_ATTR_VENDOR_ID, id); + if (res != WIFI_SUCCESS) + return res; + + res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd); + if (res != WIFI_SUCCESS) + return res; + + if (mIface != -1) + res = set_iface_id(mIface); + + return res; +} + + +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} + +wifi_error WifiCommand::requestResponse() +{ + wifi_error err = create(); /* create the message */ + if (err != WIFI_SUCCESS) + return err; + + return requestResponse(mMsg); +} + +wifi_error WifiCommand::requestResponse(WifiRequest& request) +{ + int err = 0; + + struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) + goto out; + + err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */ + if (err < 0) + goto out; + + err = 1; + + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this); + + while (err > 0) { /* wait for reply */ + int res = nl_recvmsgs(mInfo->cmd_sock, cb); + if (res) { + ALOGE("nl80211: %s->nl_recvmsgs failed: %d", __FUNCTION__, res); + } + } +out: + nl_cb_put(cb); + mMsg.destroy(); + return mapKernelErrortoWifiHalError(err); +} + +wifi_error WifiCommand::requestEvent(int cmd) +{ + + int status; + wifi_error res = wifi_register_handler(wifiHandle(), cmd, event_handler, + this); + if (res != WIFI_SUCCESS) + return res; + + res = create(); /* create the message */ + if (res != WIFI_SUCCESS) + goto out; + + status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + + res = mCondition.wait(); + if (res != WIFI_SUCCESS) + goto out; + +out: + wifi_unregister_handler(wifiHandle(), cmd); + return res; +} + +wifi_error WifiCommand::requestVendorEvent(uint32_t id, int subcmd) { + int status; + wifi_error res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, + event_handler, this); + if (res != WIFI_SUCCESS) + return res; + + res = create(); /* create the message */ + if (res != WIFI_SUCCESS) + goto out; + + status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */ + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + + res = mCondition.wait(); + if (res != WIFI_SUCCESS) + goto out; + +out: + wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); + return res; +} + +/* Event handlers */ +int WifiCommand::response_handler(struct nl_msg *msg, void *arg) { + WifiCommand *cmd = (WifiCommand *)arg; + WifiEvent reply(msg); + int res = reply.parse(); + if (res < 0) { + ALOGE("Failed to parse reply message = %d", res); + return NL_SKIP; + } else { + // reply.log(); /* Don't call log() to avoid excess WiFi HAL logging */ + return cmd->handleResponse(reply); + } +} + +int WifiCommand::event_handler(struct nl_msg *msg, void *arg) { + WifiCommand *cmd = (WifiCommand *)arg; + WifiEvent event(msg); + int res = event.parse(); + if (res < 0) { + ALOGE("Failed to parse event = %d", res); + res = NL_SKIP; + } else { + res = cmd->handleEvent(event); + } + + cmd->mCondition.signal(); + return res; +} + +/* Other event handlers */ +int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) { + int *err = (int *)arg; + *err = 0; + return NL_SKIP; +} + +int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) { + int *err = (int *)arg; + *err = 0; + return NL_STOP; +} + +int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) { + int *ret = (int *)arg; + *ret = 0; + return NL_SKIP; +} + +int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) { + int *ret = (int *)arg; + *ret = err->error; + + return NL_SKIP; +} + + +WifiVendorCommand::WifiVendorCommand(wifi_handle handle, + wifi_request_id id, + u32 vendor_id, + u32 subcmd) + : WifiCommand(handle, id), mVendor_id(vendor_id), mSubcmd(subcmd), + mVendorData(NULL), mDataLen(0) +{ + ALOGV("WifiVendorCommand %p created vendor_id:0x%x subcmd:%u", + this, mVendor_id, mSubcmd); +} + +WifiVendorCommand::~WifiVendorCommand() +{ + //ALOGV("~WifiVendorCommand %p destroyed", this); + //mVendorData is not destroyed here. Assumption + //is that VendorData is specific to each Vendor and they + //are responsible for owning the same. +} + +// Override this method to parse reply and dig out data; save it +// in the corresponding object +int WifiVendorCommand::handleResponse(WifiEvent &reply) +{ + struct nlattr **tb = reply.attributes(); + struct genlmsghdr *gnlh = reply.header(); + + if (gnlh->cmd == NL80211_CMD_VENDOR) { + if (tb[NL80211_ATTR_VENDOR_DATA]) { + mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]); + mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); + } + } + return NL_SKIP; +} + +// Override this method to parse event and dig out data; +// save it in the object +int WifiVendorCommand::handleEvent(WifiEvent &event) +{ + struct nlattr **tb = event.attributes(); + struct genlmsghdr *gnlh = event.header(); + + if (gnlh->cmd == NL80211_CMD_VENDOR) { + /* Vendor Event */ + if (!tb[NL80211_ATTR_VENDOR_ID] || + !tb[NL80211_ATTR_VENDOR_SUBCMD]) + return NL_SKIP; + + mVendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]); + mSubcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]); + + ALOGV("%s: Vendor event: vendor_id=0x%x subcmd=%u", + __FUNCTION__, mVendor_id, mSubcmd); + + if (tb[NL80211_ATTR_VENDOR_DATA]) { + mVendorData = (char *)nla_data(tb[NL80211_ATTR_VENDOR_DATA]); + mDataLen = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); + ALOGV("%s: Vendor data len received:%d", __FUNCTION__, mDataLen); + hexdump(mVendorData, mDataLen); + } + } + return NL_SKIP; +} + +wifi_error WifiVendorCommand::create() { + int ifindex; + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + // insert the oui in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + goto out; + + // insert the subcmd in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + if (ret != WIFI_SUCCESS) + goto out; + + //Insert the vendor specific data + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) + goto out; + hexdump(mVendorData, mDataLen); + + //insert the iface id to be "wlan0" + ifindex = if_nametoindex("wlan0"); + ret = mMsg.set_iface_id(ifindex); +out: + return ret; +} + +wifi_error WifiVendorCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +wifi_error WifiVendorCommand::requestEvent() +{ + wifi_error res = requestVendorEvent(mVendor_id, mSubcmd); + return res; +} + +wifi_error WifiVendorCommand::put_u8(int attribute, uint8_t value) +{ + return mMsg.put_u8(attribute, value); +} + +wifi_error WifiVendorCommand::put_u16(int attribute, uint16_t value) +{ + return mMsg.put_u16(attribute, value); +} + +wifi_error WifiVendorCommand::put_u32(int attribute, uint32_t value) +{ + return mMsg.put_u32(attribute, value); +} + +wifi_error WifiVendorCommand::put_u64(int attribute, uint64_t value) +{ + return mMsg.put_u64(attribute, value); +} + +wifi_error WifiVendorCommand::put_s8(int attribute, s8 value) +{ + return mMsg.put_s8(attribute, value); +} + +wifi_error WifiVendorCommand::put_s16(int attribute, s16 value) +{ + return mMsg.put_s16(attribute, value); +} + +wifi_error WifiVendorCommand::put_s32(int attribute, s32 value) +{ + return mMsg.put_s32(attribute, value); +} + +wifi_error WifiVendorCommand::put_s64(int attribute, s64 value) +{ + return mMsg.put_s64(attribute, value); +} + +wifi_error WifiVendorCommand::put_flag(int attribute) +{ + return mMsg.put_flag(attribute); +} + +u8 WifiVendorCommand::get_u8(const struct nlattr *nla) +{ + return mMsg.get_u8(nla); +} + +u16 WifiVendorCommand::get_u16(const struct nlattr *nla) +{ + return mMsg.get_u16(nla); +} + +u32 WifiVendorCommand::get_u32(const struct nlattr *nla) +{ + return mMsg.get_u32(nla); +} + +u64 WifiVendorCommand::get_u64(const struct nlattr *nla) +{ + return mMsg.get_u64(nla); +} + +s8 WifiVendorCommand::get_s8(const struct nlattr *nla) +{ + return mMsg.get_s8(nla); +} + +s16 WifiVendorCommand::get_s16(const struct nlattr *nla) +{ + return mMsg.get_s16(nla); +} + +s32 WifiVendorCommand::get_s32(const struct nlattr *nla) +{ + return mMsg.get_s32(nla); +} + +s64 WifiVendorCommand::get_s64(const struct nlattr *nla) +{ + return mMsg.get_s64(nla); +} + +wifi_error WifiVendorCommand::put_ipv6_addr(int attribute, uint8_t value[16]) +{ + return mMsg.put_ipv6_addr(attribute, value); +} + +wifi_error WifiVendorCommand::put_string(int attribute, const char *value) +{ + return mMsg.put_string(attribute, value); +} + +wifi_error WifiVendorCommand::put_addr(int attribute, mac_addr value) +{ + return mMsg.put_addr(attribute, value); +} + +struct nlattr * WifiVendorCommand::attr_start(int attribute) +{ + return mMsg.attr_start(attribute); +} + +void WifiVendorCommand::attr_end(struct nlattr *attribute) +{ + return mMsg.attr_end(attribute); +} + +wifi_error WifiVendorCommand::set_iface_id(const char* name) +{ + unsigned ifindex = if_nametoindex(name); + return mMsg.set_iface_id(ifindex); +} + +wifi_error WifiVendorCommand::put_bytes(int attribute, + const char *data, + int len) +{ + return mMsg.put_bytes(attribute, data, len); +} + +wifi_error WifiVendorCommand::get_mac_addr(struct nlattr **tb_vendor, + int attribute, + mac_addr addr) +{ + if (!tb_vendor[attribute]) { + ALOGE("Failed to get attribute : %d", attribute); + return WIFI_ERROR_INVALID_ARGS; + } + if (!addr) { + ALOGE("addr is NULL"); + return WIFI_ERROR_INVALID_ARGS; + } + + if (nla_len(tb_vendor[attribute]) != sizeof(mac_addr)) { + ALOGE("Invalid mac addr lenght\n"); + return WIFI_ERROR_INVALID_ARGS; + } + + memcpy(addr, (u8 *)nla_data(tb_vendor[attribute]), + nla_len(tb_vendor[attribute])); + + return WIFI_SUCCESS; +} + +wifi_error initialize_vendor_cmd(wifi_interface_handle iface, + wifi_request_id id, + u32 subcmd, + WifiVendorCommand **vCommand) +{ + wifi_error ret; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + *vCommand = new WifiVendorCommand(wifiHandle, id, + OUI_QCA, + subcmd); + if (*vCommand == NULL) { + ALOGE("%s: Object creation failed", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = (*vCommand)->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = (*vCommand)->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + return WIFI_SUCCESS; + +cleanup: + delete *vCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/cpp_bindings.h b/wcn6740/qcwcn/wifi_hal/cpp_bindings.h new file mode 100644 index 0000000..4ddb93e --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/cpp_bindings.h @@ -0,0 +1,511 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Not a Contribution + */ + +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __WIFI_HAL_CPP_BINDINGS_H__ +#define __WIFI_HAL_CPP_BINDINGS_H__ + +#include "wifi_hal.h" +#include "common.h" +#include "sync.h" + +class WifiEvent +{ + /* TODO: remove this when nl headers are updated */ + static const unsigned NL80211_ATTR_MAX_INTERNAL = 256; +private: + struct nl_msg *mMsg; + struct genlmsghdr *mHeader; + struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1]; + +public: + WifiEvent(nl_msg *msg) { + mMsg = msg; + mHeader = NULL; + memset(mAttributes, 0, sizeof(mAttributes)); + } + ~WifiEvent() { + /* don't destroy mMsg; it doesn't belong to us */ + } + + void log(); + + int parse(); + + genlmsghdr *header() { + return mHeader; + } + + int get_cmd() { + return mHeader->cmd; + } + + int get_vendor_id() { + return get_u32(NL80211_ATTR_VENDOR_ID); + } + + int get_vendor_subcmd() { + return get_u32(NL80211_ATTR_VENDOR_SUBCMD); + } + + void *get_vendor_data() { + return get_data(NL80211_ATTR_VENDOR_DATA); + } + + int get_vendor_data_len() { + return get_len(NL80211_ATTR_VENDOR_DATA); + } + + const char *get_cmdString(); + + nlattr ** attributes() { + return mAttributes; + } + + nlattr *get_attribute(int attribute) { + return mAttributes[attribute]; + } + + uint8_t get_u8(int attribute) { + return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0; + } + + uint16_t get_u16(int attribute) { + return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0; + } + + uint32_t get_u32(int attribute) { + return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0; + } + + uint64_t get_u64(int attribute) { + return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0; + } + + int get_len(int attribute) { + return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0; + } + + void *get_data(int attribute) { + return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL; + } + +private: + WifiEvent(const WifiEvent&); // hide copy constructor to prevent copies +}; + +class nl_iterator { + struct nlattr *pos; + int rem; +public: + nl_iterator(struct nlattr *attr) { + pos = (struct nlattr *)nla_data(attr); + rem = nla_len(attr); + } + bool has_next() { + return nla_ok(pos, rem); + } + void next() { + pos = (struct nlattr *)nla_next(pos, &(rem)); + } + struct nlattr *get() { + return pos; + } + uint16_t get_type() { + return pos->nla_type; + } + uint8_t get_u8() { + return nla_get_u8(pos); + } + uint16_t get_u16() { + return nla_get_u16(pos); + } + uint32_t get_u32() { + return nla_get_u32(pos); + } + uint64_t get_u64() { + return nla_get_u64(pos); + } + void* get_data() { + return nla_data(pos); + } + int get_len() { + return nla_len(pos); + } +private: + nl_iterator(const nl_iterator&); // hide copy constructor to prevent copies +}; + +class WifiRequest +{ +private: + int mFamily; + int mIface; + struct nl_msg *mMsg; + +public: + WifiRequest(int family) { + mMsg = NULL; + mFamily = family; + mIface = -1; + } + + WifiRequest(int family, int iface) { + mMsg = NULL; + mFamily = family; + mIface = iface; + } + + ~WifiRequest() { + destroy(); + } + + void destroy() { + if (mMsg) { + nlmsg_free(mMsg); + mMsg = NULL; + } + } + + nl_msg *getMessage() { + return mMsg; + } + + /* Command assembly helpers */ + wifi_error create(int family, uint8_t cmd, int flags, int hdrlen); + wifi_error create(uint8_t cmd, int flags, int hdrlen) { + return create(mFamily, cmd, flags, hdrlen); + } + wifi_error create(uint8_t cmd) { + return create(mFamily, cmd, 0, 0); + } + + wifi_error create(uint32_t id, int subcmd); + + wifi_error wifi_nla_put(struct nl_msg *msg, int attr, + int attrlen, const void *data) + { + int status; + + status = nla_put(msg, attr, attrlen, data); + if (status < 0) + ALOGE("Failed to put attr with size = %d, type = %d, error = %d", + attrlen, attr, status); + return mapKernelErrortoWifiHalError(status); + } + wifi_error put_u8(int attribute, uint8_t value) { + return wifi_nla_put(mMsg, attribute, sizeof(value), &value); + } + wifi_error put_u16(int attribute, uint16_t value) { + return wifi_nla_put(mMsg, attribute, sizeof(value), &value); + } + wifi_error put_u32(int attribute, uint32_t value) { + return wifi_nla_put(mMsg, attribute, sizeof(value), &value); + } + + wifi_error put_u64(int attribute, uint64_t value) { + return wifi_nla_put(mMsg, attribute, sizeof(value), &value); + } + + wifi_error put_s8(int attribute, s8 value) { + return wifi_nla_put(mMsg, attribute, sizeof(int8_t), &value); + } + wifi_error put_s16(int attribute, s16 value) { + return wifi_nla_put(mMsg, attribute, sizeof(int16_t), &value); + } + wifi_error put_s32(int attribute, s32 value) { + return wifi_nla_put(mMsg, attribute, sizeof(int32_t), &value); + } + wifi_error put_s64(int attribute, s64 value) { + return wifi_nla_put(mMsg, attribute, sizeof(int64_t), &value); + } + wifi_error put_flag(int attribute) { + int status; + + status = nla_put_flag(mMsg, attribute); + if(status < 0) + ALOGE("Failed to put flag attr of type = %d, error = %d", + attribute, status); + return mapKernelErrortoWifiHalError(status); + } + + u8 get_u8(const struct nlattr *nla) + { + return *(u8 *) nla_data(nla); + } + u16 get_u16(const struct nlattr *nla) + { + return *(u16 *) nla_data(nla); + } + u32 get_u32(const struct nlattr *nla) + { + return *(u32 *) nla_data(nla); + } + u64 get_u64(const struct nlattr *nla) + { + return *(u64 *) nla_data(nla); + } + + s8 get_s8(const struct nlattr *nla) + { + return *(s8 *) nla_data(nla); + } + + s16 get_s16(const struct nlattr *nla) + { + return *(s16 *) nla_data(nla); + } + s32 get_s32(const struct nlattr *nla) + { + return *(s32 *) nla_data(nla); + } + s64 get_s64(const struct nlattr *nla) + { + return *(s64 *) nla_data(nla); + } + + wifi_error put_ipv6_addr(int attribute, uint8_t *value) { + return wifi_nla_put(mMsg, attribute, 16, value); + } + + wifi_error put_string(int attribute, const char *value) { + return wifi_nla_put(mMsg, attribute, strlen(value) + 1, value); + } + wifi_error put_addr(int attribute, mac_addr value) { + return wifi_nla_put(mMsg, attribute, sizeof(mac_addr), value); + } + + struct nlattr * attr_start(int attribute) { + return nla_nest_start(mMsg, attribute); + } + void attr_end(struct nlattr *attr) { + nla_nest_end(mMsg, attr); + } + + wifi_error set_iface_id(int ifindex) { + return put_u32(NL80211_ATTR_IFINDEX, ifindex); + } + + wifi_error put_bytes(int attribute, const char *data, int len) { + return wifi_nla_put(mMsg, attribute, len, data); + } + +private: + WifiRequest(const WifiRequest&); // hide copy constructor to prevent copies + +}; + +class WifiCommand +{ +protected: + hal_info *mInfo; + WifiRequest mMsg; + Condition mCondition; + wifi_request_id mId; + interface_info *mIfaceInfo; +public: + WifiCommand(wifi_handle handle, wifi_request_id id) + : mMsg(getHalInfo(handle)->nl80211_family_id), mId(id) + { + mIfaceInfo = NULL; + mInfo = getHalInfo(handle); + } + + WifiCommand(wifi_interface_handle iface, wifi_request_id id) + : mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id), mId(id) + { + mIfaceInfo = getIfaceInfo(iface); + mInfo = getHalInfo(iface); + } + + virtual ~WifiCommand() { + } + + wifi_request_id id() { + return mId; + } + + virtual wifi_error create() { + /* by default there is no way to cancel */ + return WIFI_ERROR_NOT_SUPPORTED; + } + + virtual wifi_error cancel() { + /* by default there is no way to cancel */ + return WIFI_ERROR_NOT_SUPPORTED; + } + + wifi_error requestResponse(); + wifi_error requestEvent(int cmd); + wifi_error requestVendorEvent(uint32_t id, int subcmd); + wifi_error requestResponse(WifiRequest& request); + +protected: + wifi_handle wifiHandle() { + return getWifiHandle(mInfo); + } + + wifi_interface_handle ifaceHandle() { + return getIfaceHandle(mIfaceInfo); + } + + int familyId() { + return mInfo->nl80211_family_id; + } + + int ifaceId() { + return mIfaceInfo->id; + } + + /* Override this method to parse reply and dig out data; save it in the object */ + virtual int handleResponse(WifiEvent& reply) { + UNUSED(reply); + return NL_SKIP; + } + + /* Override this method to parse event and dig out data; save it in the object */ + virtual int handleEvent(WifiEvent& event) { + UNUSED(event); + return NL_SKIP; + } + + int registerHandler(int cmd) { + return wifi_register_handler(wifiHandle(), cmd, &event_handler, this); + } + + void unregisterHandler(int cmd) { + wifi_unregister_handler(wifiHandle(), cmd); + } + + wifi_error registerVendorHandler(uint32_t id, int subcmd) { + return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this); + } + + void unregisterVendorHandler(uint32_t id, int subcmd) { + wifi_unregister_vendor_handler(wifiHandle(), id, subcmd); + } + +private: + WifiCommand(const WifiCommand& ); // hide copy constructor to prevent copies + + /* Event handling */ + static int response_handler(struct nl_msg *msg, void *arg); + + static int event_handler(struct nl_msg *msg, void *arg); + + /* Other event handlers */ + static int valid_handler(struct nl_msg *msg, void *arg); + + static int ack_handler(struct nl_msg *msg, void *arg); + + static int finish_handler(struct nl_msg *msg, void *arg); + + static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg); +}; + +//WifiVendorCommand class +class WifiVendorCommand: public WifiCommand +{ +protected: + u32 mVendor_id; + u32 mSubcmd; + char *mVendorData; + u32 mDataLen; + + +public: + WifiVendorCommand(wifi_handle handle, wifi_request_id id, u32 vendor_id, u32 subcmd); + + virtual ~WifiVendorCommand(); + + virtual wifi_error create(); + + virtual wifi_error requestResponse(); + + virtual wifi_error requestEvent(); + + virtual wifi_error put_u8(int attribute, uint8_t value); + + virtual wifi_error put_u16(int attribute, uint16_t value); + + virtual wifi_error put_u32(int attribute, uint32_t value); + + virtual wifi_error put_u64(int attribute, uint64_t value); + + virtual wifi_error put_s8(int attribute, s8 value); + + virtual wifi_error put_s16(int attribute, s16 value); + + virtual wifi_error put_s32(int attribute, s32 value); + + virtual wifi_error put_s64(int attribute, s64 value); + + wifi_error put_flag(int attribute); + + virtual u8 get_u8(const struct nlattr *nla); + virtual u16 get_u16(const struct nlattr *nla); + virtual u32 get_u32(const struct nlattr *nla); + virtual u64 get_u64(const struct nlattr *nla); + + virtual s8 get_s8(const struct nlattr *nla); + virtual s16 get_s16(const struct nlattr *nla); + virtual s32 get_s32(const struct nlattr *nla); + virtual s64 get_s64(const struct nlattr *nla); + + virtual wifi_error put_ipv6_addr(int attribute, uint8_t value[16]); + + virtual wifi_error put_string(int attribute, const char *value); + + virtual wifi_error put_addr(int attribute, mac_addr value); + + virtual struct nlattr * attr_start(int attribute); + + virtual void attr_end(struct nlattr *attribute); + + virtual wifi_error set_iface_id(const char* name); + + virtual wifi_error put_bytes(int attribute, const char *data, int len); + + virtual wifi_error get_mac_addr(struct nlattr **tb_vendor, + int attribute, + mac_addr addr); + +protected: + + /* Override this method to parse reply and dig out data; save it in the corresponding + object */ + virtual int handleResponse(WifiEvent &reply); + + /* Override this method to parse event and dig out data; save it in the object */ + virtual int handleEvent(WifiEvent &event); +}; + +/* nl message processing macros (required to pass C++ type checks) */ + +#define for_each_attr(pos, nla, rem) \ + for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \ + nla_ok(pos, rem); \ + pos = (nlattr *)nla_next(pos, &(rem))) + +wifi_error initialize_vendor_cmd(wifi_interface_handle iface, + wifi_request_id id, + u32 subcmd, + WifiVendorCommand **vCommand); +#endif diff --git a/wcn6740/qcwcn/wifi_hal/gscan.cpp b/wcn6740/qcwcn/wifi_hal/gscan.cpp new file mode 100644 index 0000000..03a5fb4 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/gscan.cpp @@ -0,0 +1,2292 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sync.h" +#define LOG_TAG "WifiHAL" +#include <utils/Log.h> +#include <time.h> +#include <errno.h> +#include <stdlib.h> + +#include "common.h" +#include "cpp_bindings.h" +#include "gscancommand.h" +#include "gscan_event_handler.h" +#include "vendor_definitions.h" + +#define GSCAN_EVENT_WAIT_TIME_SECONDS 4 +#define WIFI_SCANNING_MAC_OUI_LENGTH 3 +#define EPNO_NO_NETWORKS 0 + +/* BSSID blacklist */ +typedef struct { + int num_bssid; // number of blacklisted BSSIDs + mac_addr bssids[MAX_BLACKLIST_BSSID]; // blacklisted BSSIDs +} wifi_bssid_params; + +/* Used to handle gscan command events from driver/firmware.*/ +typedef struct gscan_event_handlers_s { + GScanCommandEventHandler *gscanStartCmdEventHandler; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + GScanCommandEventHandler *gScanSetSsidHotlistCmdEventHandler; + GScanCommandEventHandler *gScanSetPnoListCmdEventHandler; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; +} gscan_event_handlers; + +wifi_error initializeGscanHandlers(hal_info *info) +{ + info->gscan_handlers = (gscan_event_handlers *)malloc(sizeof(gscan_event_handlers)); + if (info->gscan_handlers) { + memset(info->gscan_handlers, 0, sizeof(gscan_event_handlers)); + } + else { + ALOGE("%s: Allocation of gscan event handlers failed", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + return WIFI_SUCCESS; +} + +wifi_error cleanupGscanHandlers(hal_info *info) +{ + gscan_event_handlers* event_handlers; + if (info && info->gscan_handlers) { + event_handlers = (gscan_event_handlers*) info->gscan_handlers; + if (event_handlers->gscanStartCmdEventHandler) { + delete event_handlers->gscanStartCmdEventHandler; + } + if (event_handlers->gScanSetBssidHotlistCmdEventHandler) { + delete event_handlers->gScanSetBssidHotlistCmdEventHandler; + } + if (event_handlers->gScanSetSignificantChangeCmdEventHandler) { + delete event_handlers->gScanSetSignificantChangeCmdEventHandler; + } + if (event_handlers->gScanSetSsidHotlistCmdEventHandler) { + delete event_handlers->gScanSetSsidHotlistCmdEventHandler; + } + if (event_handlers->gScanSetPnoListCmdEventHandler) { + delete event_handlers->gScanSetPnoListCmdEventHandler; + } + if (event_handlers->gScanPnoSetPasspointListCmdEventHandler) { + delete event_handlers->gScanPnoSetPasspointListCmdEventHandler; + } + memset(event_handlers, 0, sizeof(gscan_event_handlers)); + free(info->gscan_handlers); + info->gscan_handlers = NULL; + return WIFI_SUCCESS; + } + ALOGE ("%s: info or info->gscan_handlers NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; +} + +/* Implementation of the API functions exposed in gscan.h */ +wifi_error wifi_get_valid_channels(wifi_interface_handle handle, + int band, int max_channels, wifi_channel *channels, int *num_channels) +{ + int requestId; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid(); + ALOGV("%s: RequestId:%d band:%d max_channels:%d", __FUNCTION__, + requestId, band, max_channels); + + if (channels == NULL) { + ALOGE("%s: NULL channels pointer provided. Exit.", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + gScanCommand = new GScanCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + requestId) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND, + band) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS, + max_channels) ) + { + goto cleanup; + } + gScanCommand->attr_end(nlData); + /* Populate the input received from caller/framework. */ + gScanCommand->setMaxChannels(max_channels); + gScanCommand->setChannels(channels); + gScanCommand->setNumChannelsPtr(num_channels); + + /* Send the msg and wait for a response. */ + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete gScanCommand; + return ret; +} + +wifi_error wifi_get_gscan_capabilities(wifi_interface_handle handle, + wifi_gscan_capabilities *capabilities) +{ + wifi_handle wifiHandle = getWifiHandle(handle); + hal_info *info = getHalInfo(wifiHandle); + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (capabilities == NULL) { + ALOGE("%s: NULL capabilities pointer provided. Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + memcpy(capabilities, &info->capa.gscan_capa, sizeof(wifi_gscan_capabilities)); + + return WIFI_SUCCESS; +} + +wifi_error wifi_start_gscan(wifi_request_id id, + wifi_interface_handle iface, + wifi_scan_cmd_params params, + wifi_scan_result_handler handler) +{ + wifi_error ret; + u32 i, j; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + u32 num_scan_buckets, numChannelSpecs; + wifi_scan_bucket_spec bucketSpec; + struct nlattr *nlBuckectSpecList; + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanStartCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ALOGV("%s: RequestId:%d ", __FUNCTION__, id); + /* Wi-Fi HAL doesn't need to check if a similar request to start gscan was + * made earlier. If start_gscan() is called while another gscan is already + * running, the request will be sent down to driver and firmware. If new + * request is successfully honored, then Wi-Fi HAL will use the new request + * id for the gScanStartCmdEventHandler object. + */ + gScanCommand = new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_START); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + num_scan_buckets = (unsigned int)params.num_buckets > MAX_BUCKETS ? + MAX_BUCKETS : params.num_buckets; + + ALOGV("%s: Base Period:%d Max_ap_per_scan:%d " + "Threshold_percent:%d Threshold_num_scans:%d " + "num_buckets:%d", __FUNCTION__, params.base_period, + params.max_ap_per_scan, params.report_threshold_percent, + params.report_threshold_num_scans, num_scan_buckets); + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD, + params.base_period) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN, + params.max_ap_per_scan) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT, + params.report_threshold_percent) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS, + params.report_threshold_num_scans) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS, + num_scan_buckets)) + { + goto cleanup; + } + + nlBuckectSpecList = + gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC); + /* Add NL attributes for scan bucket specs . */ + for (i = 0; i < num_scan_buckets; i++) { + bucketSpec = params.buckets[i]; + numChannelSpecs = (unsigned int)bucketSpec.num_channels > MAX_CHANNELS ? + MAX_CHANNELS : bucketSpec.num_channels; + + ALOGV("%s: Index: %d Bucket Id:%d Band:%d Period:%d ReportEvent:%d " + "numChannelSpecs:%d max_period:%d base:%d step_count:%d", + __FUNCTION__, i, bucketSpec.bucket, bucketSpec.band, + bucketSpec.period, bucketSpec.report_events, + numChannelSpecs, bucketSpec.max_period, + bucketSpec.base, bucketSpec.step_count); + + struct nlattr *nlBucketSpec = gScanCommand->attr_start(i); + if (gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX, + bucketSpec.bucket) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND, + bucketSpec.band) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD, + bucketSpec.period) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS, + bucketSpec.report_events) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS, + numChannelSpecs) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_MAX_PERIOD, + bucketSpec.max_period) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BASE, + bucketSpec.base) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_STEP_COUNT, + bucketSpec.step_count)) + { + goto cleanup; + } + + struct nlattr *nl_channelSpecList = + gScanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC); + + /* Add NL attributes for scan channel specs . */ + for (j = 0; j < numChannelSpecs; j++) { + struct nlattr *nl_channelSpec = gScanCommand->attr_start(j); + wifi_scan_channel_spec channel_spec = bucketSpec.channels[j]; + + ALOGV("%s: Channel Spec Index:%d Channel:%d Dwell Time:%d " + "passive:%d", __FUNCTION__, j, channel_spec.channel, + channel_spec.dwellTimeMs, channel_spec.passive); + + if ( gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL, + channel_spec.channel) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME, + channel_spec.dwellTimeMs) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE, + channel_spec.passive) ) + { + goto cleanup; + } + + gScanCommand->attr_end(nl_channelSpec); + } + gScanCommand->attr_end(nl_channelSpecList); + gScanCommand->attr_end(nlBucketSpec); + } + gScanCommand->attr_end(nlBuckectSpecList); + + gScanCommand->attr_end(nlData); + + /* Set the callback handler functions for related events. */ + GScanCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_full_scan_result = handler.on_full_scan_result; + callbackHandler.on_scan_event = handler.on_scan_event; + + /* Create an object to handle the related events from firmware/driver. */ + if (gScanStartCmdEventHandler == NULL) { + gScanStartCmdEventHandler = new GScanCommandEventHandler( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_START, + callbackHandler); + if (gScanStartCmdEventHandler == NULL) { + ALOGE("%s: Error gScanStartCmdEventHandler NULL", __FUNCTION__); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + event_handlers->gscanStartCmdEventHandler = gScanStartCmdEventHandler; + } else { + gScanStartCmdEventHandler->setCallbackHandler(callbackHandler); + } + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s : requestResponse Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + if (gScanStartCmdEventHandler != NULL) { + gScanStartCmdEventHandler->set_request_id(id); + gScanStartCmdEventHandler->enableEventHandling(); + } + +cleanup: + delete gScanCommand; + /* Disable Event Handling if ret != 0 */ + if ((ret != WIFI_SUCCESS) && gScanStartCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanStartCmdEventHandler->disableEventHandling(); + } + return ret; + +} + +wifi_error wifi_stop_gscan(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanStartCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanStartCmdEventHandler = event_handlers->gscanStartCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (gScanStartCmdEventHandler == NULL || + gScanStartCmdEventHandler->isEventHandlingEnabled() == false) { + ALOGE("%s: GSCAN isn't running or already stopped. " + "Nothing to do. Exit", __FUNCTION__); + return WIFI_ERROR_NOT_AVAILABLE; + } + + gScanCommand = new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + gScanCommand->attr_end(nlData); + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + /* Disable Event Handling. */ + if (gScanStartCmdEventHandler) { + gScanStartCmdEventHandler->disableEventHandling(); + } + +cleanup: + delete gScanCommand; + return ret; +} + +/* Set the GSCAN BSSID Hotlist. */ +wifi_error wifi_set_bssid_hotlist(wifi_request_id id, + wifi_interface_handle iface, + wifi_bssid_hotlist_params params, + wifi_hotlist_ap_found_handler handler) +{ + int i, numAp; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData, *nlApThresholdParamList; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetBssidHotlistCmdEventHandler = + event_handlers->gScanSetBssidHotlistCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* Wi-Fi HAL doesn't need to check if a similar request to set bssid + * hotlist was made earlier. If set_bssid_hotlist() is called while + * another one is running, the request will be sent down to driver and + * firmware. If the new request is successfully honored, then Wi-Fi HAL + * will use the new request id for the gScanSetBssidHotlistCmdEventHandler + * object. + */ + + gScanCommand = + new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + numAp = (unsigned int)params.num_bssid > MAX_HOTLIST_APS ? + MAX_HOTLIST_APS : params.num_bssid; + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE, + params.lost_ap_sample_size) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP, + numAp)) + { + goto cleanup; + } + + ALOGV("%s: lost_ap_sample_size:%d numAp:%d", __FUNCTION__, + params.lost_ap_sample_size, numAp); + /* Add the vendor specific attributes for the NL command. */ + nlApThresholdParamList = + gScanCommand->attr_start( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM); + if (!nlApThresholdParamList) + goto cleanup; + + /* Add nested NL attributes for AP Threshold Param. */ + for (i = 0; i < numAp; i++) { + ap_threshold_param apThreshold = params.ap[i]; + struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i); + if (!nlApThresholdParam) + goto cleanup; + if (gScanCommand->put_addr( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID, + apThreshold.bssid) || + gScanCommand->put_s32( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, + apThreshold.low) || + gScanCommand->put_s32( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, + apThreshold.high)) + { + goto cleanup; + } + ALOGV("%s: Index:%d BssId: %hhx:%hhx:%hhx:%hhx:%hhx:%hhx " + "Threshold low:%d high:%d", __FUNCTION__, i, + apThreshold.bssid[0], apThreshold.bssid[1], + apThreshold.bssid[2], apThreshold.bssid[3], + apThreshold.bssid[4], apThreshold.bssid[5], + apThreshold.low, apThreshold.high); + gScanCommand->attr_end(nlApThresholdParam); + } + + gScanCommand->attr_end(nlApThresholdParamList); + + gScanCommand->attr_end(nlData); + + GScanCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_hotlist_ap_found = handler.on_hotlist_ap_found; + callbackHandler.on_hotlist_ap_lost = handler.on_hotlist_ap_lost; + + /* Create an object of the event handler class to take care of the + * asychronous events on the north-bound. + */ + if (gScanSetBssidHotlistCmdEventHandler == NULL) { + gScanSetBssidHotlistCmdEventHandler = new GScanCommandEventHandler( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST, + callbackHandler); + if (gScanSetBssidHotlistCmdEventHandler == NULL) { + ALOGE("%s: Error instantiating " + "gScanSetBssidHotlistCmdEventHandler.", __FUNCTION__); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + event_handlers->gScanSetBssidHotlistCmdEventHandler = + gScanSetBssidHotlistCmdEventHandler; + } else { + gScanSetBssidHotlistCmdEventHandler->setCallbackHandler(callbackHandler); + } + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + if (gScanSetBssidHotlistCmdEventHandler != NULL) { + gScanSetBssidHotlistCmdEventHandler->set_request_id(id); + gScanSetBssidHotlistCmdEventHandler->enableEventHandling(); + } + +cleanup: + delete gScanCommand; + /* Disable Event Handling if ret != 0 */ + if ((ret != WIFI_SUCCESS) && gScanSetBssidHotlistCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetBssidHotlistCmdEventHandler->disableEventHandling(); + } + return ret; +} + +wifi_error wifi_reset_bssid_hotlist(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetBssidHotlistCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetBssidHotlistCmdEventHandler = + event_handlers->gScanSetBssidHotlistCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (gScanSetBssidHotlistCmdEventHandler == NULL || + (gScanSetBssidHotlistCmdEventHandler->isEventHandlingEnabled() == + false)) { + ALOGE("wifi_reset_bssid_hotlist: GSCAN bssid_hotlist isn't set. " + "Nothing to do. Exit"); + return WIFI_ERROR_NOT_AVAILABLE; + } + + gScanCommand = new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST); + + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + gScanCommand->attr_end(nlData); + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + /* Disable Event Handling. */ + if (gScanSetBssidHotlistCmdEventHandler) { + gScanSetBssidHotlistCmdEventHandler->disableEventHandling(); + } + +cleanup: + delete gScanCommand; + return ret; +} + +/* Set the GSCAN Significant AP Change list. */ +wifi_error wifi_set_significant_change_handler(wifi_request_id id, + wifi_interface_handle iface, + wifi_significant_change_params params, + wifi_significant_change_handler handler) +{ + int i, numAp; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData, *nlApThresholdParamList; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSignificantChangeCmdEventHandler = + event_handlers->gScanSetSignificantChangeCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* Wi-Fi HAL doesn't need to check if a similar request to set significant + * change list was made earlier. If set_significant_change() is called while + * another one is running, the request will be sent down to driver and + * firmware. If the new request is successfully honored, then Wi-Fi HAL + * will use the new request id for the gScanSetSignificantChangeCmdEventHandler + * object. + */ + + gScanCommand = new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + numAp = (unsigned int)params.num_bssid > MAX_SIGNIFICANT_CHANGE_APS ? + MAX_SIGNIFICANT_CHANGE_APS : params.num_bssid; + + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE, + params.rssi_sample_size) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE, + params.lost_ap_sample_size) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING, + params.min_breaching) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP, + numAp)) + { + goto cleanup; + } + + ALOGV("%s: Number of AP params:%d Rssi_sample_size:%d " + "lost_ap_sample_size:%d min_breaching:%d", __FUNCTION__, + numAp, params.rssi_sample_size, params.lost_ap_sample_size, + params.min_breaching); + + /* Add the vendor specific attributes for the NL command. */ + nlApThresholdParamList = + gScanCommand->attr_start( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM); + if (!nlApThresholdParamList) + goto cleanup; + + /* Add nested NL attributes for AP Threshold Param list. */ + for (i = 0; i < numAp; i++) { + ap_threshold_param apThreshold = params.ap[i]; + struct nlattr *nlApThresholdParam = gScanCommand->attr_start(i); + if (!nlApThresholdParam) + goto cleanup; + if ( gScanCommand->put_addr( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID, + apThreshold.bssid) || + gScanCommand->put_s32( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW, + apThreshold.low) || + gScanCommand->put_s32( + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH, + apThreshold.high)) + { + goto cleanup; + } + ALOGV("%s: ap[%d].bssid:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx " + "ap[%d].low:%d ap[%d].high:%d", __FUNCTION__, + i, + apThreshold.bssid[0], apThreshold.bssid[1], + apThreshold.bssid[2], apThreshold.bssid[3], + apThreshold.bssid[4], apThreshold.bssid[5], + i, apThreshold.low, i, apThreshold.high); + gScanCommand->attr_end(nlApThresholdParam); + } + + gScanCommand->attr_end(nlApThresholdParamList); + + gScanCommand->attr_end(nlData); + + GScanCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_significant_change = handler.on_significant_change; + + /* Create an object of the event handler class to take care of the + * asychronous events on the north-bound. + */ + if (gScanSetSignificantChangeCmdEventHandler == NULL) { + gScanSetSignificantChangeCmdEventHandler = + new GScanCommandEventHandler( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE, + callbackHandler); + if (gScanSetSignificantChangeCmdEventHandler == NULL) { + ALOGE("%s: Error in instantiating, " + "gScanSetSignificantChangeCmdEventHandler.", + __FUNCTION__); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + event_handlers->gScanSetSignificantChangeCmdEventHandler = + gScanSetSignificantChangeCmdEventHandler; + } else { + gScanSetSignificantChangeCmdEventHandler->setCallbackHandler(callbackHandler); + } + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + if (gScanSetSignificantChangeCmdEventHandler != NULL) { + gScanSetSignificantChangeCmdEventHandler->set_request_id(id); + gScanSetSignificantChangeCmdEventHandler->enableEventHandling(); + } + +cleanup: + /* Disable Event Handling if ret != 0 */ + if ((ret != WIFI_SUCCESS) && gScanSetSignificantChangeCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetSignificantChangeCmdEventHandler->disableEventHandling(); + } + delete gScanCommand; + return ret; +} + +/* Clear the GSCAN Significant AP change list. */ +wifi_error wifi_reset_significant_change_handler(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetSignificantChangeCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetSignificantChangeCmdEventHandler = + event_handlers->gScanSetSignificantChangeCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (gScanSetSignificantChangeCmdEventHandler == NULL || + (gScanSetSignificantChangeCmdEventHandler->isEventHandlingEnabled() == + false)) { + ALOGE("wifi_reset_significant_change_handler: GSCAN significant_change" + " isn't set. Nothing to do. Exit"); + return WIFI_ERROR_NOT_AVAILABLE; + } + + gScanCommand = + new GScanCommand + ( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + gScanCommand->attr_end(nlData); + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + /* Disable Event Handling. */ + if (gScanSetSignificantChangeCmdEventHandler) { + gScanSetSignificantChangeCmdEventHandler->disableEventHandling(); + } + +cleanup: + delete gScanCommand; + return ret; +} + +/* Get the GSCAN cached scan results. */ +wifi_error wifi_get_cached_gscan_results(wifi_interface_handle iface, + byte flush, int max, + wifi_cached_scan_results *results, + int *num) +{ + int requestId, retRequestRsp = 0; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* No request id from caller, so generate one and pass it on to the driver. */ + /* Generate it randomly */ + requestId = get_requestid(); + + if (results == NULL || num == NULL) { + ALOGE("%s: NULL pointer provided. Exit.", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + gScanCommand = new GScanCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = gScanCommand->allocRspParams(eGScanGetCachedResultsRspParams); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to allocate memory for response struct. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + ret = gScanCommand->allocCachedResultsTemp(max, results); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to allocate memory for temp gscan cached list. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Clear the destination cached results list before copying results. */ + memset(results, 0, max * sizeof(wifi_cached_scan_results)); + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + requestId) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH, + flush) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX, + max)) + { + goto cleanup; + } + + ALOGV("%s: flush:%d max:%d", __FUNCTION__, flush, max); + gScanCommand->attr_end(nlData); + + retRequestRsp = gScanCommand->requestResponse(); + if (retRequestRsp != 0) { + ALOGE("%s: requestResponse Error:%d", + __FUNCTION__, retRequestRsp); + /* It's possible to get ETIMEDOUT after receiving few results from + * driver. Copy and forward them to framework. + */ + if (retRequestRsp != -ETIMEDOUT) { + /* Proceed to cleanup & return no results */ + goto cleanup; + } + } + + /* No more data, copy the parsed results into the caller's results array */ + ret = gScanCommand->copyCachedScanResults(num, results); + ALOGV("%s: max: %d, num:%d", __FUNCTION__, max, *num); + + if (!ret) { + /* If requestResponse returned a TIMEOUT */ + if (retRequestRsp == -ETIMEDOUT) { + if (*num > 0) { + /* Mark scan results as incomplete for the last scan_id */ + results[(*num)-1].flags = WIFI_SCAN_FLAG_INTERRUPTED; + ALOGV("%s: Timeout happened. Mark scan results as incomplete " + "for scan_id:%d", __FUNCTION__, results[(*num)-1].scan_id); + ret = WIFI_SUCCESS; + } else + ret = WIFI_ERROR_TIMED_OUT; + } + } +cleanup: + gScanCommand->freeRspParams(eGScanGetCachedResultsRspParams); + delete gScanCommand; + return ret; +} + +/* Random MAC OUI for PNO */ +wifi_error wifi_set_scanning_mac_oui(wifi_interface_handle handle, oui scan_oui) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + interface_info *iinfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + vCommand = new WifiVendorCommand(wifiHandle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI); + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ALOGV("%s: MAC_OUI - %02x:%02x:%02x", __FUNCTION__, + scan_oui[0], scan_oui[1], scan_oui[2]); + + /* Add the fixed part of the mac_oui to the nl command */ + ret = vCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI, + (char *)scan_oui, + WIFI_SCANNING_MAC_OUI_LENGTH); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + +cleanup: + delete vCommand; + return ret; +} + + +GScanCommand::GScanCommand(wifi_handle handle, int id, u32 vendor_id, + u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + /* Initialize the member data variables here */ + mGetCachedResultsRspParams = NULL; + mChannels = NULL; + mMaxChannels = 0; + mNumChannelsPtr = NULL; + + mRequestId = id; + memset(&mHandler, 0,sizeof(mHandler)); +} + +GScanCommand::~GScanCommand() +{ + unregisterVendorHandler(mVendor_id, mSubcmd); +} + + +/* This function implements creation of Vendor command */ +wifi_error GScanCommand::create() { + wifi_error ret; + + ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + if (ret != WIFI_SUCCESS) + return ret; + + ALOGV("%s: mVendor_id = %d, Subcmd = %d.", + __FUNCTION__, mVendor_id, mSubcmd); + + return ret; +} + +wifi_error GScanCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +int GScanCommand::handleResponse(WifiEvent &reply) +{ + int i = 0; + wifi_error ret = WIFI_SUCCESS; + u32 val; + + WifiVendorCommand::handleResponse(reply); + + struct nlattr *tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *)mVendorData,mDataLen, NULL); + + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS: + { + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS" + " not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + val = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS]); + + val = val > (unsigned int)mMaxChannels ? + (unsigned int)mMaxChannels : val; + *mNumChannelsPtr = val; + + /* Extract the list of channels. */ + if (*mNumChannelsPtr > 0 ) { + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS" + " not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + nla_memcpy(mChannels, + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS], + sizeof(wifi_channel) * (*mNumChannelsPtr)); + } + char buf[256]; + size_t len = 0; + for (i = 0; i < *mNumChannelsPtr && len < sizeof(buf); i++) { + len += snprintf(buf + len, sizeof(buf) - len, "%u ", + *(mChannels + i)); + } + ALOGV("%s: Num Channels %d: List of valid channels are: %s", + __FUNCTION__, *mNumChannelsPtr, buf); + + } + break; + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS: + { + wifi_request_id id; + u32 numResults = 0; + int firstScanIdInPatch = -1; + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) { + ALOGE("%s: GSCAN_RESULTS_REQUEST_ID not" + "found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, just ignore it. */ + if (id != mRequestId) { + ALOGV("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + break; + } + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not" + "found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + /* Read num of cached scan results in this data chunk. Note that + * this value doesn't represent the number of unique gscan scan Ids + * since the first scan id in this new chunk could be similar to + * the last scan id in the previous chunk. + */ + numResults = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + ALOGV("%s: num Cached results in this fragment:%d", + __FUNCTION__, numResults); + + if (!mGetCachedResultsRspParams) { + ALOGE("%s: mGetCachedResultsRspParams is NULL, exit.", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + + /* To support fragmentation from firmware, monitor the + * MORE_DATA flag and cache results until MORE_DATA = 0. + */ + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA " + "not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } else { + mGetCachedResultsRspParams->more_data = nla_get_u8( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); + } + + /* No data in this chunk so skip this chunk */ + if (numResults == 0) { + return NL_SKIP; + } + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]) { + ALOGE("GSCAN_CACHED_RESULTS_SCAN_ID not found"); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + + /* Get the first Scan-Id in this chuck of cached results. */ + firstScanIdInPatch = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID]); + + ALOGV("More data: %d, firstScanIdInPatch: %d, lastProcessedScanId: %d", + mGetCachedResultsRspParams->more_data, firstScanIdInPatch, + mGetCachedResultsRspParams->lastProcessedScanId); + + if (numResults) { + if (firstScanIdInPatch != + mGetCachedResultsRspParams->lastProcessedScanId) { + /* New result scan Id block, update the starting index. */ + mGetCachedResultsRspParams->cachedResultsStartingIndex++; + } + + ret = gscan_get_cached_results( + mGetCachedResultsRspParams->cached_results, + tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + break; + } + } + break; + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong GScan subcmd response received %d", + __FUNCTION__, mSubcmd); + } + + /* A parsing error occurred, do the cleanup of gscan result lists. */ + if (ret) { + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS: + { + ALOGE("%s: Parsing error, free CachedResultsRspParams", + __FUNCTION__); + freeRspParams(eGScanGetCachedResultsRspParams); + } + break; + default: + ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd); + } + } + return NL_SKIP; +} + +/* Called to parse and extract cached results. */ +wifi_error GScanCommand:: gscan_get_cached_results( + wifi_cached_scan_results *cached_results, + struct nlattr **tb_vendor) +{ + int j = 0; + struct nlattr *scanResultsInfo, *wifiScanResultsInfo; + int rem = 0, remResults = 0; + u32 len = 0, numScanResults = 0; + int i = mGetCachedResultsRspParams->cachedResultsStartingIndex; + ALOGV("%s: starting counter: %d", __FUNCTION__, i); + + for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST]); + nla_ok(scanResultsInfo, rem) && i < mGetCachedResultsRspParams->max; + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID + ]) + { + ALOGE("%s: GSCAN_CACHED_RESULTS_SCAN_ID" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].scan_id = + nla_get_u32( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID + ]); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS + ]) + { + ALOGE("%s: GSCAN_CACHED_RESULTS_FLAGS " + "not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].flags = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]) + { + ALOGI("%s: GSCAN_RESULTS_BUCKETS_SCANNED" + "not found", __FUNCTION__); + } else { + cached_results[i].buckets_scanned = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]); + } + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + ]) + { + ALOGE("%s: RESULTS_NUM_RESULTS_AVAILABLE " + "not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + numScanResults = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + + if (mGetCachedResultsRspParams->lastProcessedScanId != + cached_results[i].scan_id) { + j = 0; /* reset wifi_scan_result counter */ + cached_results[i].num_results = 0; + ALOGV("parsing: *lastProcessedScanId [%d] !=" + " cached_results[%d].scan_id:%d, j:%d " + "numScanResults: %d", + mGetCachedResultsRspParams->lastProcessedScanId, i, + cached_results[i].scan_id, j, numScanResults); + mGetCachedResultsRspParams->lastProcessedScanId = + cached_results[i].scan_id; + mGetCachedResultsRspParams->wifiScanResultsStartingIndex = 0; + /* Increment the number of cached scan results received */ + mGetCachedResultsRspParams->num_cached_results++; + } else { + j = mGetCachedResultsRspParams->wifiScanResultsStartingIndex; + ALOGV("parsing: *lastProcessedScanId [%d] == " + "cached_results[%d].scan_id:%d, j:%d " + "numScanResults:%d", + mGetCachedResultsRspParams->lastProcessedScanId, i, + cached_results[i].scan_id, j, numScanResults); + } + + ALOGV("%s: scan_id %d ", __FUNCTION__, + cached_results[i].scan_id); + ALOGV("%s: flags %u ", __FUNCTION__, + cached_results[i].flags); + + for (wifiScanResultsInfo = (struct nlattr *) nla_data(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + remResults = nla_len(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); + nla_ok(wifiScanResultsInfo, remResults); + wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(remResults))) + { + struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(wifiScanResultsInfo), + nla_len(wifiScanResultsInfo), NULL); + if (j < MAX_AP_CACHE_PER_SCAN) { + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_TIME_STAMP not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].results[j].ts = + nla_get_u64( + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_SSID not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = + sizeof(cached_results[i].results[j].ssid) <= len ? + sizeof(cached_results[i].results[j].ssid) : len; + memcpy((void *)&cached_results[i].results[j].ssid, + nla_data( + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), + len); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_BSSID not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len( + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = + sizeof(cached_results[i].results[j].bssid) <= len ? + sizeof(cached_results[i].results[j].bssid) : len; + memcpy(&cached_results[i].results[j].bssid, + nla_data( + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), + len); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_CHANNEL not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].results[j].channel = + nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_RSSI not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].results[j].rssi = + get_s32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_RTT not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].results[j].rtt = + nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + if (! + tb3[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD + ]) + { + ALOGE("%s: " + "RESULTS_SCAN_RESULT_RTT_SD not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + cached_results[i].results[j].rtt_sd = + nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); +#ifdef QC_HAL_DEBUG + /* Enable these prints for debugging if needed. */ + ALOGD("%s: ts %" PRId64, __FUNCTION__, + cached_results[i].results[j].ts); + ALOGD("%s: SSID %s ", __FUNCTION__, + cached_results[i].results[j].ssid); + ALOGD("%s: BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n", + __FUNCTION__, cached_results[i].results[j].bssid[0], + cached_results[i].results[j].bssid[1], + cached_results[i].results[j].bssid[2], + cached_results[i].results[j].bssid[3], + cached_results[i].results[j].bssid[4], + cached_results[i].results[j].bssid[5]); + ALOGD("%s: channel %d ", __FUNCTION__, + cached_results[i].results[j].channel); + ALOGD("%s: rssi %d ", __FUNCTION__, + cached_results[i].results[j].rssi); + ALOGD("%s: rtt %" PRId64, __FUNCTION__, + cached_results[i].results[j].rtt); + ALOGD("%s: rtt_sd %" PRId64, __FUNCTION__, + cached_results[i].results[j].rtt_sd); +#endif + /* Increment loop index for next record */ + j++; + /* For this scan id, update the wifiScanResultsStartingIndex + * and number of cached results parsed so far. + */ + mGetCachedResultsRspParams->wifiScanResultsStartingIndex = j; + cached_results[i].num_results++; + } else { + /* We already parsed and stored up to max wifi_scan_results + * specified by the caller. Now, continue to loop over NL + * entries in order to properly update NL parsing pointer + * so it points to the next scan_id results. + */ + ALOGD("%s: loop index:%d > max num" + " of wifi_scan_results:%d for gscan cached results" + " bucket:%d. Dummy loop", __FUNCTION__, + j, MAX_AP_CACHE_PER_SCAN, i); + } + } + ALOGV("%s: cached_results[%d].num_results: %d ", __FUNCTION__, + i, cached_results[i].num_results); + /* Increment loop index for next cached scan result record */ + i++; + } + /* Increment starting index of filling cached results received */ + if (mGetCachedResultsRspParams->num_cached_results <= 1024) + mGetCachedResultsRspParams->cachedResultsStartingIndex = + mGetCachedResultsRspParams->num_cached_results - 1; + return WIFI_SUCCESS; +} + +/* Set the GSCAN BSSID Hotlist. */ +wifi_error wifi_set_epno_list(wifi_request_id id, + wifi_interface_handle iface, + const wifi_epno_params *epno_params, + wifi_epno_handler handler) +{ + int i, num_networks; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData, *nlPnoParamList; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanSetPnoListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanSetPnoListCmdEventHandler = + event_handlers->gScanSetPnoListCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { + ALOGE("%s: Enhanced PNO is not supported by the driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO + * list was made earlier. If wifi_set_epno_list() is called while + * another one is running, the request will be sent down to driver and + * firmware. If the new request is successfully honored, then Wi-Fi HAL + * will use the new request id for the gScanSetPnoListCmdEventHandler + * object. + */ + + gScanCommand = + new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + num_networks = (unsigned int)epno_params->num_networks > MAX_EPNO_NETWORKS ? + MAX_EPNO_NETWORKS : epno_params->num_networks; + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI, + epno_params->min5GHz_rssi) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI, + epno_params->min24GHz_rssi) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX, + epno_params->initial_score_max) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS, + epno_params->current_connection_bonus) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS, + epno_params->same_network_bonus) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS, + epno_params->secure_bonus) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS, + epno_params->band5GHz_bonus) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS, + num_networks)) + { + ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlPnoParamList = + gScanCommand->attr_start( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST); + if (!nlPnoParamList) { + ALOGE("%s: Failed to add attr. PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add nested NL attributes for ePno List. */ + for (i = 0; i < num_networks; i++) { + wifi_epno_network pnoNetwork = epno_params->networks[i]; + struct nlattr *nlPnoNetwork = gScanCommand->attr_start(i); + if (!nlPnoNetwork) { + ALOGE("%s: Failed attr_start for nlPnoNetwork. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + if (gScanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID, + pnoNetwork.ssid) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS, + pnoNetwork.flags) || + gScanCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT, + pnoNetwork.auth_bit_field)) + { + ALOGE("%s: Failed to add PNO_SET_LIST_PARAM_EPNO_NETWORK_*. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + gScanCommand->attr_end(nlPnoNetwork); + } + + gScanCommand->attr_end(nlPnoParamList); + + gScanCommand->attr_end(nlData); + + GScanCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_pno_network_found = handler.on_network_found; + + /* Create an object of the event handler class to take care of the + * asychronous events on the north-bound. + */ + if (gScanSetPnoListCmdEventHandler == NULL) { + gScanSetPnoListCmdEventHandler = new GScanCommandEventHandler( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST, + callbackHandler); + if (gScanSetPnoListCmdEventHandler == NULL) { + ALOGE("%s: Error instantiating " + "gScanSetPnoListCmdEventHandler.", __FUNCTION__); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + event_handlers->gScanSetPnoListCmdEventHandler = + gScanSetPnoListCmdEventHandler; + } else { + gScanSetPnoListCmdEventHandler->setCallbackHandler(callbackHandler); + } + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + if (gScanSetPnoListCmdEventHandler != NULL) { + gScanSetPnoListCmdEventHandler->set_request_id(id); + gScanSetPnoListCmdEventHandler->enableEventHandling(); + } + +cleanup: + delete gScanCommand; + /* Disable Event Handling if ret != 0 */ + if ((ret != WIFI_SUCCESS) && gScanSetPnoListCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanSetPnoListCmdEventHandler->disableEventHandling(); + } + return ret; +} + +/* Reset the ePNO list - no ePNO networks should be matched after this */ +wifi_error wifi_reset_epno_list(wifi_request_id id, wifi_interface_handle iface) +{ + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { + ALOGE("%s: Enhanced PNO is not supported by the driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + gScanCommand = new GScanCommand(wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS, + EPNO_NO_NETWORKS)) + { + ALOGE("%s: Failed to add vendor atributes Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + gScanCommand->attr_end(nlData); + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + +cleanup: + delete gScanCommand; + return ret; +} + +/* Set the ePNO Passpoint List. */ +wifi_error wifi_set_passpoint_list(wifi_request_id id, + wifi_interface_handle iface, int num, + wifi_passpoint_network *networks, + wifi_passpoint_event_handler handler) +{ + int i; + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData, *nlPasspointNetworksParamList; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanPnoSetPasspointListCmdEventHandler = + event_handlers->gScanPnoSetPasspointListCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { + ALOGE("%s: Enhanced PNO is not supported by the driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* Wi-Fi HAL doesn't need to check if a similar request to set ePNO + * passpoint list was made earlier. If wifi_set_passpoint_list() is called + * while another one is running, the request will be sent down to driver and + * firmware. If the new request is successfully honored, then Wi-Fi HAL + * will use the new request id for the + * gScanPnoSetPasspointListCmdEventHandler object. + */ + gScanCommand = + new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST); + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, + id) || + gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM, + num)) + { + ALOGE("%s: Failed to add vendor atributes. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlPasspointNetworksParamList = + gScanCommand->attr_start( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY); + if (!nlPasspointNetworksParamList) { + ALOGE("%s: Failed attr_start for PASSPOINT_LIST_PARAM_NETWORK_ARRAY. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add nested NL attributes for Passpoint List param. */ + for (i = 0; i < num; i++) { + wifi_passpoint_network passpointNetwork = networks[i]; + struct nlattr *nlPasspointNetworkParam = gScanCommand->attr_start(i); + if (!nlPasspointNetworkParam) { + ALOGE("%s: Failed attr_start for nlPasspointNetworkParam. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + if (gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID, + passpointNetwork.id) || + gScanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM, + passpointNetwork.realm) || + gScanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID, + (char*)passpointNetwork.roamingConsortiumIds, + 16 * sizeof(int64_t)) || + gScanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN, + (char*)passpointNetwork.plmn, 3 * sizeof(u8))) + { + ALOGE("%s: Failed to add PNO_PASSPOINT_NETWORK_PARAM_ROAM_* attr. " + "Error:%d", __FUNCTION__, ret); + goto cleanup; + } + gScanCommand->attr_end(nlPasspointNetworkParam); + } + + gScanCommand->attr_end(nlPasspointNetworksParamList); + + gScanCommand->attr_end(nlData); + + GScanCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_passpoint_network_found = + handler.on_passpoint_network_found; + + /* Create an object of the event handler class to take care of the + * asychronous events on the north-bound. + */ + if (gScanPnoSetPasspointListCmdEventHandler == NULL) { + gScanPnoSetPasspointListCmdEventHandler = new GScanCommandEventHandler( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST, + callbackHandler); + if (gScanPnoSetPasspointListCmdEventHandler == NULL) { + ALOGE("%s: Error instantiating " + "gScanPnoSetPasspointListCmdEventHandler.", __FUNCTION__); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + event_handlers->gScanPnoSetPasspointListCmdEventHandler = + gScanPnoSetPasspointListCmdEventHandler; + } else { + gScanPnoSetPasspointListCmdEventHandler->setCallbackHandler(callbackHandler); + } + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + if (gScanPnoSetPasspointListCmdEventHandler != NULL) { + gScanPnoSetPasspointListCmdEventHandler->set_request_id(id); + gScanPnoSetPasspointListCmdEventHandler->enableEventHandling(); + } + +cleanup: + delete gScanCommand; + /* Disable Event Handling if ret != 0 */ + if ((ret != WIFI_SUCCESS) && gScanPnoSetPasspointListCmdEventHandler) { + ALOGI("%s: Error ret:%d, disable event handling", + __FUNCTION__, ret); + gScanPnoSetPasspointListCmdEventHandler->disableEventHandling(); + } + return ret; +} + +wifi_error wifi_reset_passpoint_list(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + GScanCommand *gScanCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + gscan_event_handlers* event_handlers; + GScanCommandEventHandler *gScanPnoSetPasspointListCmdEventHandler; + + event_handlers = (gscan_event_handlers*)info->gscan_handlers; + gScanPnoSetPasspointListCmdEventHandler = + event_handlers->gScanPnoSetPasspointListCmdEventHandler; + + if (!(info->supported_feature_set & WIFI_FEATURE_HAL_EPNO)) { + ALOGE("%s: Enhanced PNO is not supported by the driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (gScanPnoSetPasspointListCmdEventHandler == NULL || + (gScanPnoSetPasspointListCmdEventHandler->isEventHandlingEnabled() == + false)) { + ALOGE("wifi_reset_passpoint_list: ePNO passpoint_list isn't set. " + "Nothing to do. Exit."); + return WIFI_ERROR_NOT_AVAILABLE; + } + + gScanCommand = new GScanCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PNO_RESET_PASSPOINT_LIST); + + if (gScanCommand == NULL) { + ALOGE("%s: Error GScanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = gScanCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create the NL msg. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = gScanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set iface id. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = gScanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: Failed to add attribute NL80211_ATTR_VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + ret = gScanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, id); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to add vendor data attributes. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + gScanCommand->attr_end(nlData); + + ret = gScanCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + /* Disable Event Handling. */ + if (gScanPnoSetPasspointListCmdEventHandler) { + gScanPnoSetPasspointListCmdEventHandler->disableEventHandling(); + } + +cleanup: + delete gScanCommand; + return ret; +} + +wifi_error GScanCommand::allocCachedResultsTemp(int max, + wifi_cached_scan_results *cached_results) +{ + /* Alloc memory for "max" number of cached results. */ + mGetCachedResultsRspParams->cached_results = + (wifi_cached_scan_results*) + malloc(max * sizeof(wifi_cached_scan_results)); + if (!mGetCachedResultsRspParams->cached_results) { + ALOGE("%s: Failed to allocate memory for " + "mGetCachedResultsRspParams->cached_results.", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + memset(mGetCachedResultsRspParams->cached_results, 0, + max * sizeof(wifi_cached_scan_results)); + + mGetCachedResultsRspParams->max = max; + + return WIFI_SUCCESS; +} + +/* + * Allocates memory for the subCmd response struct and initializes status = -1 + */ +wifi_error GScanCommand::allocRspParams(eGScanRspRarams cmd) +{ + switch(cmd) + { + case eGScanGetCachedResultsRspParams: + mGetCachedResultsRspParams = (GScanGetCachedResultsRspParams *) + malloc(sizeof(GScanGetCachedResultsRspParams)); + if (!mGetCachedResultsRspParams) + return WIFI_ERROR_OUT_OF_MEMORY; + + mGetCachedResultsRspParams->num_cached_results = 0; + mGetCachedResultsRspParams->more_data = false; + mGetCachedResultsRspParams->cachedResultsStartingIndex = -1; + mGetCachedResultsRspParams->lastProcessedScanId = -1; + mGetCachedResultsRspParams->wifiScanResultsStartingIndex = -1; + mGetCachedResultsRspParams->max = 0; + mGetCachedResultsRspParams->cached_results = NULL; + break; + default: + ALOGD("%s: Wrong request for alloc.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + return WIFI_SUCCESS; +} + +void GScanCommand::freeRspParams(eGScanRspRarams cmd) +{ + switch(cmd) + { + case eGScanGetCachedResultsRspParams: + if (mGetCachedResultsRspParams) { + if (mGetCachedResultsRspParams->cached_results) { + free(mGetCachedResultsRspParams->cached_results); + mGetCachedResultsRspParams->cached_results = NULL; + } + free(mGetCachedResultsRspParams); + mGetCachedResultsRspParams = NULL; + } + break; + default: + ALOGD("%s: Wrong request for free.", __FUNCTION__); + } +} + +wifi_error GScanCommand::copyCachedScanResults( + int *numResults, + wifi_cached_scan_results *cached_results) +{ + wifi_error ret = WIFI_SUCCESS; + int i; + wifi_cached_scan_results *cachedResultRsp; + + if (mGetCachedResultsRspParams && cached_results) + { + /* Populate the number of parsed cached results. */ + *numResults = mGetCachedResultsRspParams->num_cached_results; + + for (i = 0; i < *numResults; i++) { + cachedResultRsp = &mGetCachedResultsRspParams->cached_results[i]; + cached_results[i].scan_id = cachedResultRsp->scan_id; + cached_results[i].flags = cachedResultRsp->flags; + cached_results[i].num_results = cachedResultRsp->num_results; + cached_results[i].buckets_scanned = cachedResultRsp->buckets_scanned; + + if (!cached_results[i].num_results) { + ALOGI("Error: cached_results[%d].num_results=0", i); + continue; + } + + ALOGV("copyCachedScanResults: " + "cached_results[%d].num_results : %d", + i, cached_results[i].num_results); + + memcpy(cached_results[i].results, + cachedResultRsp->results, + cached_results[i].num_results * sizeof(wifi_scan_result)); + } + } else { + ALOGE("%s: mGetCachedResultsRspParams is NULL", __FUNCTION__); + *numResults = 0; + ret = WIFI_ERROR_INVALID_ARGS; + } + return ret; +} + +void GScanCommand::setMaxChannels(int max_channels) { + mMaxChannels = max_channels; +} + +void GScanCommand::setChannels(int *channels) { + mChannels = channels; +} + +void GScanCommand::setNumChannelsPtr(int *num_channels) { + mNumChannelsPtr = num_channels; +} diff --git a/wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp new file mode 100644 index 0000000..074d64b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp @@ -0,0 +1,1929 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> +#include "gscan_event_handler.h" + +/* This function implements creation of Vendor command event handler. */ +wifi_error GScanCommandEventHandler::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + + return ret; +} + +int GScanCommandEventHandler::get_request_id() +{ + return mRequestId; +} + +void GScanCommandEventHandler::set_request_id(int request_id) +{ + mRequestId = request_id; +} + +void GScanCommandEventHandler::enableEventHandling() +{ + mEventHandlingEnabled = true; +} + +void GScanCommandEventHandler::disableEventHandling() +{ + mEventHandlingEnabled = false; +} + +bool GScanCommandEventHandler::isEventHandlingEnabled() +{ + return mEventHandlingEnabled; +} + +void GScanCommandEventHandler::setCallbackHandler(GScanCallbackHandler handler) +{ + mHandler = handler; +} + +GScanCommandEventHandler::GScanCommandEventHandler(wifi_handle handle, int id, + u32 vendor_id, + u32 subcmd, + GScanCallbackHandler handler) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + int ret = 0; + mRequestId = id; + mHandler = handler; + mSubCommandId = subcmd; + mHotlistApFoundResults = NULL; + mHotlistApFoundNumResults = 0; + mHotlistApFoundMoreData = false; + mHotlistApLostResults = NULL; + mHotlistApLostNumResults = 0; + mHotlistApLostMoreData = false; + mSignificantChangeResults = NULL; + mSignificantChangeNumResults = 0; + mSignificantChangeMoreData = false; + mHotlistSsidFoundNumResults = 0; + mHotlistSsidFoundMoreData = false; + mHotlistSsidLostNumResults = 0; + mHotlistSsidLostMoreData = false; + mHotlistSsidFoundResults = NULL; + mHotlistSsidLostResults = NULL; + mPnoNetworkFoundResults = NULL; + mPnoNetworkFoundNumResults = 0; + mPnoNetworkFoundMoreData = false; + mPasspointNetworkFoundResult = NULL; + mPasspointAnqp = NULL; + mPasspointAnqpLen = 0; + mPasspointNetId = -1; + mEventHandlingEnabled = false; + + switch(mSubCommandId) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START: + { + /* Register handlers for northbound asychronous scan events. */ + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE) || + registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) || + registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT); + if (ret) + ALOGE("%s: Error in registering handler for " + "GSCAN_START. \n", __FUNCTION__); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE: + { + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE); + if (ret) + ALOGE("%s: Error in registering handler for " + "GSCAN_SIGNIFICANT_CHANGE. \n", __FUNCTION__); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST: + { + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND); + if (ret) + ALOGE("%s: Error in registering handler for" + " GSCAN_HOTLIST_AP_FOUND. \n", __FUNCTION__); + + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST); + if (ret) + ALOGE("%s: Error in registering handler for" + " GSCAN_HOTLIST_AP_LOST. \n", __FUNCTION__); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST: + { + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND); + if (ret) + ALOGE("%s: Error in registering handler for" + " PNO_NETWORK_FOUND. \n", __FUNCTION__); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST: + { + ret = registerVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND); + if (ret) + ALOGE("%s: Error in registering handler for" + " PNO_PASSPOINT_NETWORK_FOUND. \n", __FUNCTION__); + } + break; + } +} + +GScanCommandEventHandler::~GScanCommandEventHandler() +{ + switch(mSubCommandId) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_START: + { + /* Unregister event handlers. */ + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE); + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT); + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE: + { + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST: + { + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND); + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST: + { + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST: + { + unregisterVendorHandler(mVendor_id, + QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND); + } + break; + } +} + +wifi_error GScanCommandEventHandler::gscan_parse_hotlist_ap_results( + u32 num_results, + wifi_scan_result *results, + u32 starting_index, + struct nlattr **tb_vendor) +{ + u32 i = starting_index; + struct nlattr *scanResultsInfo; + int rem = 0; + u32 len = 0; + ALOGV("gscan_parse_hotlist_ap_results: starting counter: %d", i); + + for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST + ]); + nla_ok(scanResultsInfo, rem); + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_TIME_STAMP not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].ts = + nla_get_u64( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_SSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = + sizeof(results->ssid) <= len ? sizeof(results->ssid) : len; + memcpy((void *)&results[i].ssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_BSSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = + sizeof(results->bssid) <= len ? sizeof(results->bssid) : len; + memcpy(&results[i].bssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_CHANNEL not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].channel = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_RSSI not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rssi = + get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_RTT not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD + ]) + { + ALOGE("gscan_parse_hotlist_ap_results: " + "RESULTS_SCAN_RESULT_RTT_SD not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt_sd = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); + + ALOGV("gscan_parse_hotlist_ap_results: ts %" PRId64 " SSID %s " + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d " + "rtt %" PRId64" rtt_sd %" PRId64, + results[i].ts, results[i].ssid, + results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], + results[i].bssid[3], results[i].bssid[4], results[i].bssid[5], + results[i].channel, results[i].rssi, results[i].rtt, + results[i].rtt_sd); + /* Increment loop index for next record */ + i++; + } + return WIFI_SUCCESS; +} + +static wifi_error gscan_get_significant_change_results(u32 num_results, + wifi_significant_change_result **results, + u32 starting_index, + struct nlattr **tb_vendor) +{ + u32 i = starting_index; + int j; + int rem = 0; + u32 len = 0; + char rssi_buf[1024]; //TODO: sizeof buf + int rem_size; + struct nlattr *scanResultsInfo; + + for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); + nla_ok(scanResultsInfo, rem); + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID + ]) + { + ALOGE("gscan_get_significant_change_results: " + "SIGNIFICANT_CHANGE_RESULT_BSSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID] + ); + len = + sizeof(results[i]->bssid) <= len ? sizeof(results[i]->bssid) : len; + memcpy(&results[i]->bssid[0], + nla_data( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID]), + len); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL + ]) + { + ALOGE("gscan_get_significant_change_results: " + "SIGNIFICANT_CHANGE_RESULT_CHANNEL not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i]->channel = + nla_get_u32( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL]); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI + ]) + { + ALOGE("gscan_get_significant_change_results: " + "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i]->num_rssi = + nla_get_u32( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI]); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST + ]) + { + ALOGE("gscan_get_significant_change_results: " + "SIGNIFICANT_CHANGE_RESULT_RSSI_LIST not found"); + return WIFI_ERROR_INVALID_ARGS; + } + + memcpy(&(results[i]->rssi[0]), + nla_data( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST] + ), results[i]->num_rssi * sizeof(wifi_rssi)); + + ALOGV("significant_change_result:%d, BSSID:" + "%02x:%02x:%02x:%02x:%02x:%02x channel:%d num_rssi:%d ", + i, results[i]->bssid[0], results[i]->bssid[1], results[i]->bssid[2], + results[i]->bssid[3], results[i]->bssid[4], results[i]->bssid[5], + results[i]->channel, results[i]->num_rssi); + + rem_size = sizeof(rssi_buf); + char *dst = rssi_buf; + for (j = 0; j < results[i]->num_rssi && rem_size > 0; j++) { + len = snprintf(dst, rem_size, "rssi[%d]:%d, ", j, results[i]->rssi[j]); + dst += len; + rem_size -= len; + } + ALOGV("RSSI LIST: %s", rssi_buf); + + /* Increment loop index to prase next record. */ + i++; + } + return WIFI_SUCCESS; +} + +wifi_error GScanCommandEventHandler::gscan_parse_hotlist_ssid_results( + u32 num_results, + wifi_scan_result *results, + u32 starting_index, + struct nlattr **tb_vendor) +{ + u32 i = starting_index; + struct nlattr *scanResultsInfo; + int rem = 0; + u32 len = 0; + + for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST + ]); + nla_ok(scanResultsInfo, rem); + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_TIME_STAMP not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].ts = + nla_get_u64( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_SSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = + sizeof(results->ssid) <= len ? sizeof(results->ssid) : len; + memcpy((void *)&results[i].ssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_BSSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = + sizeof(results->bssid) <= len ? sizeof(results->bssid) : len; + memcpy(&results[i].bssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_CHANNEL not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].channel = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_RSSI not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rssi = + get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_RTT not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD + ]) + { + ALOGE("gscan_parse_hotlist_ssid_results: " + "RESULTS_SCAN_RESULT_RTT_SD not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt_sd = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); + + ALOGV("gscan_parse_hotlist_ssid_results: ts %" PRId64 " SSID %s " + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d " + "rtt %" PRId64 " rtt_sd %" PRId64, + results[i].ts, results[i].ssid, + results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], + results[i].bssid[3], results[i].bssid[4], results[i].bssid[5], + results[i].channel, results[i].rssi, results[i].rtt, + results[i].rtt_sd); + /* Increment loop index for next record */ + i++; + } + return WIFI_SUCCESS; +} + +wifi_error GScanCommandEventHandler::gscan_parse_passpoint_network_result( + struct nlattr **tb_vendor) +{ + struct nlattr *scanResultsInfo, *wifiScanResultsInfo; + u32 resultsBufSize = 0; + u32 len = 0; + int rem = 0; + + scanResultsInfo = (struct nlattr *)nla_data( + tb_vendor + [QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST]); + + rem = nla_len( + tb_vendor + [QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST]); + + if (!nla_ok(scanResultsInfo, rem)) { + return WIFI_SUCCESS; + } + + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *)nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID]) { + ALOGE("%s: GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetId = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID]); + + for (wifiScanResultsInfo = (struct nlattr *)nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); + nla_ok(wifiScanResultsInfo, rem); + wifiScanResultsInfo = nla_next(wifiScanResultsInfo, &(rem))) { + struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *)nla_data(wifiScanResultsInfo), + nla_len(wifiScanResultsInfo), NULL); + + resultsBufSize = sizeof(wifi_scan_result); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]) { + ALOGE("%s: RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + resultsBufSize += nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]); + + /* Allocate the appropriate memory for mPasspointNetworkFoundResult */ + mPasspointNetworkFoundResult = (wifi_scan_result *)malloc(resultsBufSize); + + if (!mPasspointNetworkFoundResult) { + ALOGE("%s: Failed to alloc memory for result struct. Exit.\n", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + memset(mPasspointNetworkFoundResult, 0, resultsBufSize); + + mPasspointNetworkFoundResult->ie_length = nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP]) { + ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->ts = nla_get_u64( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP]); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]) { + ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = sizeof(mPasspointNetworkFoundResult->ssid) <= len + ? sizeof(mPasspointNetworkFoundResult->ssid) + : len; + memcpy((void *)&(mPasspointNetworkFoundResult->ssid[0]), + nla_data(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), + len); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]) { + ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = sizeof(mPasspointNetworkFoundResult->bssid) <= len + ? sizeof(mPasspointNetworkFoundResult->bssid) + : len; + memcpy( + &(mPasspointNetworkFoundResult->bssid[0]), + nla_data(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), + len); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]) { + ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->channel = nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]) { + ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->rssi = + get_s32(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]) { + ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->rtt = + nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]) { + ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->rtt_sd = nla_get_u32( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]) { + ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->beacon_period = nla_get_u16( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]) { + ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointNetworkFoundResult->capability = nla_get_u16( + tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]) { + ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + memcpy( + &(mPasspointNetworkFoundResult->ie_data[0]), + nla_data(tb3[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]), + mPasspointNetworkFoundResult->ie_length); + + ALOGV("%s: ts: %" PRId64 " SSID: %s " + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel: %d rssi: %d" + " rtt: % " PRId64 " rtt_sd %" PRId64 " ie_length %u ", + __FUNCTION__, mPasspointNetworkFoundResult->ts, + mPasspointNetworkFoundResult->ssid, + mPasspointNetworkFoundResult->bssid[0], + mPasspointNetworkFoundResult->bssid[1], + mPasspointNetworkFoundResult->bssid[2], + mPasspointNetworkFoundResult->bssid[3], + mPasspointNetworkFoundResult->bssid[4], + mPasspointNetworkFoundResult->bssid[5], + mPasspointNetworkFoundResult->channel, + mPasspointNetworkFoundResult->rssi, + mPasspointNetworkFoundResult->rtt, + mPasspointNetworkFoundResult->rtt_sd, + mPasspointNetworkFoundResult->ie_length); + ALOGV("%s: ie_data: ", __FUNCTION__); + hexdump(mPasspointNetworkFoundResult->ie_data, + mPasspointNetworkFoundResult->ie_length); + } + + if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN]) { + ALOGE("%s:PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mPasspointAnqpLen = nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN]); + + if (!mPasspointAnqpLen) { + return WIFI_SUCCESS; + } + mPasspointAnqp = (u8 *)malloc(mPasspointAnqpLen); + if (!mPasspointAnqp) { + ALOGE("%s: Failed to alloc memory for result struct. Exit.\n", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + memset(mPasspointAnqp, 0, mPasspointAnqpLen); + if (!tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP]) { + ALOGE("%s: RESULTS_PASSPOINT_MATCH_ANQP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + memcpy( + &(mPasspointAnqp[0]), + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP]), + mPasspointAnqpLen); + + ALOGV("%s: ANQP LEN:%d, ANQP IE:", __FUNCTION__, mPasspointAnqpLen); + hexdump((char *)mPasspointAnqp, mPasspointAnqpLen); + return WIFI_SUCCESS; +} + +wifi_error GScanCommandEventHandler::gscan_parse_pno_network_results( + u32 num_results, + wifi_scan_result *results, + u32 starting_index, + struct nlattr **tb_vendor) +{ + u32 i = starting_index; + struct nlattr *scanResultsInfo; + int rem = 0; + u32 len = 0; + + for (scanResultsInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST + ]); + nla_ok(scanResultsInfo, rem); + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_TIME_STAMP not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].ts = + nla_get_u64( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_SSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = + sizeof(results->ssid) <= len ? sizeof(results->ssid) : len; + memcpy((void *)&results[i].ssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_BSSID not found"); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = + sizeof(results->bssid) <= len ? sizeof(results->bssid) : len; + memcpy(&results[i].bssid, + nla_data( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_CHANNEL not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].channel = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_RSSI not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rssi = + get_s32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_RTT not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_RTT_SD not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].rtt_sd = + nla_get_u32( + tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_BEACON_PERIOD not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].beacon_period = + nla_get_u16( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]); + + if (! + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY + ]) + { + ALOGE("gscan_parse_pno_network_results: " + "RESULTS_SCAN_RESULT_CAPABILITY not found"); + return WIFI_ERROR_INVALID_ARGS; + } + results[i].capability = + nla_get_u16( + tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]); + + ALOGV("gscan_parse_pno_network_results: ts %" PRId64 " SSID %s " + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x channel %d rssi %d " + "rtt %" PRId64 " rtt_sd %" PRId64, + results[i].ts, results[i].ssid, + results[i].bssid[0], results[i].bssid[1], results[i].bssid[2], + results[i].bssid[3], results[i].bssid[4], results[i].bssid[5], + results[i].channel, results[i].rssi, results[i].rtt, + results[i].rtt_sd); + /* Increment loop index for next record */ + i++; + } + return WIFI_SUCCESS; +} + +/* This function will be the main handler for incoming (from driver) + * GScan_SUBCMD. Calls the appropriate callback handler after parsing + * the vendor data. + */ +int GScanCommandEventHandler::handleEvent(WifiEvent &event) +{ + unsigned i=0; + int ret = WIFI_SUCCESS; + wifi_scan_result *result = NULL; + struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + + if (mEventHandlingEnabled == false) + { + ALOGV("%s:Discarding event: %d", + __FUNCTION__, mSubcmd); + return NL_SKIP; + } + + WifiVendorCommand::handleEvent(event); + + nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT: + { + wifi_request_id reqId; + u32 len = 0; + u32 resultsBufSize = 0; + u32 lengthOfInfoElements = 0; + u32 buckets_scanned = 0; + + ALOGV("Event QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT " + "received."); + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) + { + ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + reqId = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If event has a different request_id, ignore that and use the + * request_id value which we're maintaining. + */ + if (reqId != mRequestId) { +#ifdef QC_HAL_DEBUG + ALOGE("%s: Event has Req. ID:%d <> Ours:%d, continue...", + __FUNCTION__, reqId, mRequestId); +#endif + reqId = mRequestId; + } + + /* Parse and extract the results. */ + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH + ]) + { + ALOGE("%s:RESULTS_SCAN_RESULT_IE_LENGTH not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + lengthOfInfoElements = + nla_get_u32( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH]); + + ALOGV("%s: RESULTS_SCAN_RESULT_IE_LENGTH =%d", + __FUNCTION__, lengthOfInfoElements); + + resultsBufSize = + lengthOfInfoElements + sizeof(wifi_scan_result); + result = (wifi_scan_result *) malloc (resultsBufSize); + if (!result) { + ALOGE("%s: Failed to alloc memory for result struct. Exit.\n", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + memset(result, 0, resultsBufSize); + + result->ie_length = lengthOfInfoElements; + + /* Extract and fill out the wifi_scan_result struct. */ + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_TIME_STAMP not found", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->ts = + nla_get_u64( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP + ]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_SSID not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + len = nla_len(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]); + len = + sizeof(result->ssid) <= len ? sizeof(result->ssid) : len; + memcpy((void *)&result->ssid, + nla_data( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID]), len); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_BSSID not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + len = nla_len( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]); + len = + sizeof(result->bssid) <= len ? sizeof(result->bssid) : len; + memcpy(&result->bssid, + nla_data( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID]), len); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_CHANNEL not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->channel = + nla_get_u32( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_RSSI not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->rssi = + get_s32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI] + ); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_RTT not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->rtt = + nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_RTT_SD not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->rtt_sd = + nla_get_u32( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_BEACON_PERIOD not found", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->beacon_period = + nla_get_u16( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_CAPABILITY not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + result->capability = + nla_get_u16( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY]); + + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA + ]) + { + ALOGE("%s: RESULTS_SCAN_RESULT_IE_DATA not found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + memcpy(&(result->ie_data[0]), + nla_data(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_DATA]), + lengthOfInfoElements); + if (! + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED + ]) + { + ALOGD("%s: RESULTS_BUCKETS_SCANNED not found", __FUNCTION__); + } else { + buckets_scanned = get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED]); + } +#ifdef QC_HAL_DEBUG + ALOGD("handleEvent:FULL_SCAN_RESULTS: ts %" PRId64, result->ts); + ALOGD("handleEvent:FULL_SCAN_RESULTS: SSID %s ", result->ssid) ; + ALOGD("handleEvent:FULL_SCAN_RESULTS: " + "BSSID: %02x:%02x:%02x:%02x:%02x:%02x \n", + result->bssid[0], result->bssid[1], result->bssid[2], + result->bssid[3], result->bssid[4], result->bssid[5]); + ALOGD("handleEvent:FULL_SCAN_RESULTS: channel %d ", + result->channel); + ALOGD("handleEvent:FULL_SCAN_RESULTS: rssi %d ", result->rssi); + ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt %" PRId64, result->rtt); + ALOGD("handleEvent:FULL_SCAN_RESULTS: rtt_sd %" PRId64, + result->rtt_sd); + ALOGD("handleEvent:FULL_SCAN_RESULTS: beacon period %d ", + result->beacon_period); + ALOGD("handleEvent:FULL_SCAN_RESULTS: capability %d ", + result->capability); + ALOGD("handleEvent:FULL_SCAN_RESULTS: IE length %d ", + result->ie_length); + + ALOGD("%s: Invoking the callback. \n", __FUNCTION__); +#endif + if (mHandler.on_full_scan_result) { + (*mHandler.on_full_scan_result)(reqId, result, buckets_scanned); + /* Reset flag and num counter. */ + free(result); + result = NULL; + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE: + { + wifi_request_id id; + +#ifdef QC_HAL_DEBUG + ALOGV("Event " + "QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE " + "received."); +#endif + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID" + "not found. Exit", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, then ignore it. */ + if (id != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + break; + } + + /* Invoke the callback func to report the number of results. */ + ALOGV("%s: Calling on_scan_event handler", __FUNCTION__); + (*mHandler.on_scan_event)(id, WIFI_SCAN_THRESHOLD_NUM_SCANS); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND: + { + wifi_request_id id; + u32 resultsBufSize = 0; + u32 numResults = 0; + u32 startingIndex, sizeOfObtainedResults; + + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, just ignore it. */ + if (id != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + break; + } + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + numResults = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + ALOGV("%s: number of results:%d", __FUNCTION__, numResults); + + /* Get the memory size of previous fragments, if any. */ + sizeOfObtainedResults = mHotlistApFoundNumResults * + sizeof(wifi_scan_result); + + mHotlistApFoundNumResults += numResults; + resultsBufSize += mHotlistApFoundNumResults * + sizeof(wifi_scan_result); + + /* Check if this chunck of scan results is a continuation of + * a previous one. + */ + if (mHotlistApFoundMoreData) { + mHotlistApFoundResults = (wifi_scan_result *) + realloc (mHotlistApFoundResults, resultsBufSize); + } else { + mHotlistApFoundResults = (wifi_scan_result *) + malloc (resultsBufSize); + } + + if (!mHotlistApFoundResults) { + ALOGE("%s: Failed to alloc memory for results array. Exit.\n", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + /* Initialize the newly allocated memory area with 0. */ + memset((u8 *)mHotlistApFoundResults + sizeOfObtainedResults, 0, + resultsBufSize - sizeOfObtainedResults); + + ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__, + mHotlistApFoundNumResults); + + /* To support fragmentation from firmware, monitor the + * MORE_DATA flag and cache results until MORE_DATA = 0. + * Only then we can pass on the results to framework through + * the callback function. + */ + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" + " found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } else { + mHotlistApFoundMoreData = nla_get_u8( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); + ALOGE("%s: More data = %d. \n", + __FUNCTION__, mHotlistApFoundMoreData); + } + + ALOGV("%s: Extract hotlist_ap_found results.\n", __FUNCTION__); + startingIndex = mHotlistApFoundNumResults - numResults; + ALOGV("%s: starting_index:%d", + __FUNCTION__, startingIndex); + ret = gscan_parse_hotlist_ap_results(numResults, + mHotlistApFoundResults, + startingIndex, + tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + break; + /* Send the results if no more result data fragments are expected */ + if (!mHotlistApFoundMoreData) { + (*mHandler.on_hotlist_ap_found)(id, + mHotlistApFoundNumResults, + mHotlistApFoundResults); + /* Reset flag and num counter. */ + free(mHotlistApFoundResults); + mHotlistApFoundResults = NULL; + mHotlistApFoundMoreData = false; + mHotlistApFoundNumResults = 0; + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST: + { + wifi_request_id id; + u32 resultsBufSize = 0; + u32 numResults = 0; + u32 startingIndex, sizeOfObtainedResults; + + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, just ignore it. */ + if (id != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + break; + } + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + numResults = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + ALOGV("%s: number of results:%d", __FUNCTION__, numResults); + + /* Get the memory size of previous fragments, if any. */ + sizeOfObtainedResults = mHotlistApLostNumResults * + sizeof(wifi_scan_result); + + mHotlistApLostNumResults += numResults; + resultsBufSize += mHotlistApLostNumResults * + sizeof(wifi_scan_result); + + /* Check if this chunck of scan results is a continuation of + * a previous one. + */ + if (mHotlistApLostMoreData) { + mHotlistApLostResults = (wifi_scan_result *) + realloc (mHotlistApLostResults, resultsBufSize); + } else { + mHotlistApLostResults = (wifi_scan_result *) + malloc (resultsBufSize); + } + + if (!mHotlistApLostResults) { + ALOGE("%s: Failed to alloc memory for results array. Exit.\n", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + /* Initialize the newly allocated memory area with 0. */ + memset((u8 *)mHotlistApLostResults + sizeOfObtainedResults, 0, + resultsBufSize - sizeOfObtainedResults); + + ALOGV("%s: Num of AP Lost results = %d. \n", __FUNCTION__, + mHotlistApLostNumResults); + + /* To support fragmentation from firmware, monitor the + * MORE_DATA flag and cache results until MORE_DATA = 0. + * Only then we can pass on the results to framework through + * the callback function. + */ + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" + " found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } else { + mHotlistApLostMoreData = nla_get_u8( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); + ALOGV("%s: More data = %d. \n", + __FUNCTION__, mHotlistApLostMoreData); + } + + ALOGV("%s: Extract hotlist_ap_Lost results.\n", __FUNCTION__); + startingIndex = mHotlistApLostNumResults - numResults; + ALOGV("%s: starting_index:%d", + __FUNCTION__, startingIndex); + ret = gscan_parse_hotlist_ap_results(numResults, + mHotlistApLostResults, + startingIndex, + tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + break; + /* Send the results if no more result data fragments are expected */ + if (!mHotlistApLostMoreData) { + (*mHandler.on_hotlist_ap_lost)(id, + mHotlistApLostNumResults, + mHotlistApLostResults); + /* Reset flag and num counter. */ + free(mHotlistApLostResults); + mHotlistApLostResults = NULL; + mHotlistApLostMoreData = false; + mHotlistApLostNumResults = 0; + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE: + { + wifi_request_id reqId; + u32 numResults = 0, sizeOfObtainedResults; + u32 startingIndex, index = 0; + struct nlattr *scanResultsInfo; + int rem = 0; + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) + { + ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + reqId = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, just ignore it. */ + if (reqId != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, reqId, mRequestId); + break; + } + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) + { + ALOGE("%s: ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found." + "Exit.", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + numResults = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + /* Get the memory size of previous fragments, if any. */ + sizeOfObtainedResults = sizeof(wifi_significant_change_result *) * + mSignificantChangeNumResults; + + index = mSignificantChangeNumResults; + mSignificantChangeNumResults += numResults; + /* + * Check if this chunck of wifi_significant_change results is a + * continuation of a previous one. + */ + if (mSignificantChangeMoreData) { + mSignificantChangeResults = + (wifi_significant_change_result **) + realloc (mSignificantChangeResults, + sizeof(wifi_significant_change_result *) * + mSignificantChangeNumResults); + } else { + mSignificantChangeResults = + (wifi_significant_change_result **) + malloc (sizeof(wifi_significant_change_result *) * + mSignificantChangeNumResults); + } + + if (!mSignificantChangeResults) { + ALOGE("%s: Failed to alloc memory for results array. Exit.\n", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + /* Initialize the newly allocated memory area with 0. */ + memset((u8 *)mSignificantChangeResults + sizeOfObtainedResults, 0, + sizeof(wifi_significant_change_result *) * + numResults); + ALOGV("%s: mSignificantChangeMoreData = %d", + __FUNCTION__, mSignificantChangeMoreData); + + for (scanResultsInfo = (struct nlattr *) nla_data(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]), + rem = nla_len(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST]); + nla_ok(scanResultsInfo, rem); + scanResultsInfo = nla_next(scanResultsInfo, &(rem))) + { + u32 num_rssi = 0; + u32 resultsBufSize = 0; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *) nla_data(scanResultsInfo), + nla_len(scanResultsInfo), NULL); + if (!tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI + ]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_" + "SIGNIFICANT_CHANGE_RESULT_NUM_RSSI not found. " + "Exit.", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + num_rssi = nla_get_u32(tb2[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI + ]); + resultsBufSize = sizeof(wifi_significant_change_result) + + num_rssi * sizeof(wifi_rssi); + mSignificantChangeResults[index] = + (wifi_significant_change_result *) malloc (resultsBufSize); + + if (!mSignificantChangeResults[index]) { + ALOGE("%s: Failed to alloc memory for results array Exit", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + /* Initialize the newly allocated memory area with 0. */ + memset((u8 *)mSignificantChangeResults[index], + 0, resultsBufSize); + + ALOGV("%s: For Significant Change results[%d], num_rssi:%d\n", + __FUNCTION__, index, num_rssi); + index++; + } + + ALOGV("%s: Extract significant change results.\n", __FUNCTION__); + startingIndex = + mSignificantChangeNumResults - numResults; + ret = gscan_get_significant_change_results(numResults, + mSignificantChangeResults, + startingIndex, + tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + break; + /* To support fragmentation from firmware, monitor the + * MORE_DATA flag and cache results until MORE_DATA = 0. + * Only then we can pass on the results to framework through + * the callback function. + */ + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" + " found. Stop parsing and exit.", __FUNCTION__); + break; + } + mSignificantChangeMoreData = nla_get_u8( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); + ALOGV("%s: More data = %d. \n", + __FUNCTION__, mSignificantChangeMoreData); + + /* Send the results if no more result fragments are expected */ + if (!mSignificantChangeMoreData) { + ALOGV("%s: Invoking the callback. \n", __FUNCTION__); + (*mHandler.on_significant_change)(reqId, + mSignificantChangeNumResults, + mSignificantChangeResults); + if (mSignificantChangeResults) { + /* Reset flag and num counter. */ + for (index = 0; index < mSignificantChangeNumResults; + index++) + { + free(mSignificantChangeResults[index]); + mSignificantChangeResults[index] = NULL; + } + free(mSignificantChangeResults); + mSignificantChangeResults = NULL; + } + mSignificantChangeNumResults = 0; + mSignificantChangeMoreData = false; + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT: + { + wifi_scan_event scanEvent; + wifi_request_id reqId; + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) + { + ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Exit.", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + reqId = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, just ignore it. */ + if (reqId != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, reqId, mRequestId); + break; + } + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]) { + ALOGE("%s: GSCAN_RESULTS_SCAN_EVENT_TYPE not" + " found. Stop parsing and exit.", __FUNCTION__); + break; + } + scanEvent = (wifi_scan_event) nla_get_u8(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE]); + + ALOGV("%s: Scan event type: %d\n", __FUNCTION__, scanEvent); + /* Send the results if no more result fragments are expected. */ + (*mHandler.on_scan_event)(reqId, scanEvent); + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND: + { + wifi_request_id id; + u32 resultsBufSize = 0; + u32 numResults = 0; + u32 startingIndex, sizeOfObtainedResults; + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) + { + /* RequestId is not provided by FW/Driver for this event */ + ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.", + __FUNCTION__); + id = mRequestId; /* Use the saved mRequestId instead. */ + } else { + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, use the saved requestId */ + if (id != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + id = mRequestId; + } + } + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_AVAILABLE not found", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + numResults = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE]); + ALOGV("%s: number of results:%d", __FUNCTION__, numResults); + + /* Get the memory size of previous fragments, if any. */ + sizeOfObtainedResults = mPnoNetworkFoundNumResults * + sizeof(wifi_scan_result); + + mPnoNetworkFoundNumResults += numResults; + resultsBufSize += mPnoNetworkFoundNumResults * + sizeof(wifi_scan_result); + + /* Check if this chunck of scan results is a continuation of + * a previous one. + */ + if (mPnoNetworkFoundMoreData) { + mPnoNetworkFoundResults = (wifi_scan_result *) + realloc (mPnoNetworkFoundResults, resultsBufSize); + } else { + mPnoNetworkFoundResults = (wifi_scan_result *) + malloc (resultsBufSize); + } + + if (!mPnoNetworkFoundResults) { + ALOGE("%s: Failed to alloc memory for results array. Exit.\n", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + /* Initialize the newly allocated memory area with 0. */ + memset((u8 *)mPnoNetworkFoundResults + sizeOfObtainedResults, 0, + resultsBufSize - sizeOfObtainedResults); + + ALOGV("%s: Num of AP FOUND results = %d. \n", __FUNCTION__, + mPnoNetworkFoundNumResults); + + /* To support fragmentation from firmware, monitor the + * MORE_DATA flag and cache results until MORE_DATA = 0. + * Only then we can pass on the results to framework through + * the callback function. + */ + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]) { + ALOGE("%s: GSCAN_RESULTS_NUM_RESULTS_MORE_DATA not" + " found", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } else { + mPnoNetworkFoundMoreData = nla_get_u8( + tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA]); + ALOGV("%s: More data = %d. \n", + __FUNCTION__, mPnoNetworkFoundMoreData); + } + + ALOGV("%s: Extract PNO_NETWORK_FOUND results.\n", __FUNCTION__); + startingIndex = mPnoNetworkFoundNumResults - numResults; + ALOGV("%s: starting_index:%d", + __FUNCTION__, startingIndex); + ret = gscan_parse_pno_network_results(numResults, + mPnoNetworkFoundResults, + startingIndex, + tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + break; + /* Send the results if no more result data fragments are expected */ + if (!mPnoNetworkFoundMoreData) { + (*mHandler.on_pno_network_found)(id, + mPnoNetworkFoundNumResults, + mPnoNetworkFoundResults); + /* Reset flag and num counter. */ + if (mPnoNetworkFoundResults) { + free(mPnoNetworkFoundResults); + mPnoNetworkFoundResults = NULL; + } + mPnoNetworkFoundMoreData = false; + mPnoNetworkFoundNumResults = 0; + } + } + break; + case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND: + { + wifi_request_id id; + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID]) + { + /* RequestId is not provided by FW/Driver for this event */ + ALOGE("%s: ATTR_GSCAN_RESULTS_REQUEST_ID not found. Continue.", + __FUNCTION__); + id = mRequestId; /* Use the saved mRequestId instead. */ + } else { + id = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_REQUEST_ID] + ); + /* If this is not for us, use the saved requestId */ + if (id != mRequestId) { + ALOGE("%s: Event has Req. ID:%d <> ours:%d", + __FUNCTION__, id, mRequestId); + id = mRequestId; + } + } + + ret = gscan_parse_passpoint_network_result(tbVendor); + /* If a parsing error occurred, exit and proceed for cleanup. */ + if (ret) + { + ALOGE("%s: gscan_parse_passpoint_network_result" + "returned error: %d.\n", __FUNCTION__, ret); + break; + } + (*mHandler.on_passpoint_network_found)(id, + mPasspointNetId, + mPasspointNetworkFoundResult, + mPasspointAnqpLen, + mPasspointAnqp); + if (mPasspointNetworkFoundResult) + { + free(mPasspointNetworkFoundResult); + mPasspointNetworkFoundResult = NULL; + } + if (mPasspointAnqp) + { + free(mPasspointAnqp); + mPasspointAnqp = NULL; + } + mPasspointNetId = -1; + mPasspointAnqpLen = 0; + } + break; + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong GScan subcmd received %d", __FUNCTION__, mSubcmd); + } + + /* A parsing error occurred, do the cleanup of gscan result lists. */ + if (ret) { + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT: + { + free(result); + result = NULL; + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND: + { + /* Reset flag and num counter. */ + free(mHotlistApFoundResults); + mHotlistApFoundResults = NULL; + mHotlistApFoundMoreData = false; + mHotlistApFoundNumResults = 0; + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE: + { + if (mSignificantChangeResults) { + for (i = 0; i < mSignificantChangeNumResults; i++) + { + if (mSignificantChangeResults[i]) { + free(mSignificantChangeResults[i]); + mSignificantChangeResults[i] = NULL; + } + } + free(mSignificantChangeResults); + mSignificantChangeResults = NULL; + } + mSignificantChangeNumResults = 0; + mSignificantChangeMoreData = false; + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE: + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT: + break; + + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST: + { + /* Reset flag and num counter. */ + free(mHotlistApLostResults); + mHotlistApLostResults = NULL; + mHotlistApLostMoreData = false; + mHotlistApLostNumResults = 0; + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND: + { + /* Reset flag and num counter. */ + if (mPnoNetworkFoundResults) { + free(mPnoNetworkFoundResults); + mPnoNetworkFoundResults = NULL; + } + mPnoNetworkFoundMoreData = false; + mPnoNetworkFoundNumResults = 0; + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND: + { + if (mPasspointNetworkFoundResult) + { + free(mPasspointNetworkFoundResult); + mPasspointNetworkFoundResult = NULL; + } + if (mPasspointAnqp) + { + free(mPasspointAnqp); + mPasspointAnqp = NULL; + } + mPasspointNetId = -1; + mPasspointAnqpLen = 0; + } + break; + + default: + ALOGE("%s: Parsing err handler: wrong GScan subcmd " + "received %d", __FUNCTION__, mSubcmd); + } + } + return NL_SKIP; +} diff --git a/wcn6740/qcwcn/wifi_hal/gscan_event_handler.h b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.h new file mode 100644 index 0000000..5384db8 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/gscan_event_handler.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_HAL_GSCAN_EVENT_HANDLE_H__ +#define __WIFI_HAL_GSCAN_EVENT_HANDLE_H__ + +#include "common.h" +#include "cpp_bindings.h" +#include "gscancommand.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +class GScanCommandEventHandler: public WifiVendorCommand +{ +private: + // TODO: derive 3 other command event handler classes from this base and separate + // the data member vars + wifi_scan_result *mHotlistApFoundResults; + wifi_scan_result *mHotlistApLostResults; + u32 mHotlistApFoundNumResults; + u32 mHotlistApLostNumResults; + bool mHotlistApFoundMoreData; + bool mHotlistApLostMoreData; + wifi_significant_change_result **mSignificantChangeResults; + u32 mSignificantChangeNumResults; + bool mSignificantChangeMoreData; + GScanCallbackHandler mHandler; + int mRequestId; + u32 mHotlistSsidFoundNumResults; + bool mHotlistSsidFoundMoreData; + u32 mHotlistSsidLostNumResults; + bool mHotlistSsidLostMoreData; + wifi_scan_result *mHotlistSsidFoundResults; + wifi_scan_result *mHotlistSsidLostResults; + wifi_scan_result *mPnoNetworkFoundResults; + u32 mPnoNetworkFoundNumResults; + bool mPnoNetworkFoundMoreData; + wifi_scan_result *mPasspointNetworkFoundResult; + byte *mPasspointAnqp; + int mPasspointAnqpLen; + int mPasspointNetId; + + /* Needed because mSubcmd gets overwritten in + * WifiVendorCommand::handleEvent() + */ + u32 mSubCommandId; + bool mEventHandlingEnabled; + +public: + GScanCommandEventHandler(wifi_handle handle, int id, u32 vendor_id, + u32 subcmd, GScanCallbackHandler nHandler); + virtual ~GScanCommandEventHandler(); + virtual wifi_error create(); + virtual int get_request_id(); + virtual void set_request_id(int request_id); + virtual int handleEvent(WifiEvent &event); + void enableEventHandling(); + void disableEventHandling(); + bool isEventHandlingEnabled(); + void setCallbackHandler(GScanCallbackHandler handler); + wifi_error gscan_parse_hotlist_ap_results( + u32 num_results, + wifi_scan_result *results, + u32 starting_index, + struct nlattr **tb_vendor); + wifi_error gscan_parse_hotlist_ssid_results( + u32 num_results, + wifi_scan_result *results, + u32 starting_index, + struct nlattr **tb_vendor); + wifi_error gscan_parse_passpoint_network_result( + struct nlattr **tb_vendor); + wifi_error gscan_parse_pno_network_results( + u32 numResults, + wifi_scan_result *mPnoNetworkFoundResults, + u32 startingIndex, + struct nlattr **tbVendor); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/gscancommand.h b/wcn6740/qcwcn/wifi_hal/gscancommand.h new file mode 100644 index 0000000..6fbc90b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/gscancommand.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_HAL_GSCAN_COMMAND_H__ +#define __WIFI_HAL_GSCAN_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif +#include "gscan.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct{ + u32 status; + u32 num_channels; + wifi_channel channels[]; +} GScanGetValidChannelsRspParams; + +typedef struct{ + wifi_gscan_capabilities capabilities; +} GScanGetCapabilitiesRspParams; + +typedef struct{ + u8 more_data; + u32 num_cached_results; + int cachedResultsStartingIndex; /* Used in filling cached scan results */ + int lastProcessedScanId; /* Last scan id in gscan cached results block */ + int wifiScanResultsStartingIndex; /* For the lastProcessedScanId */ + int max; /* max num of cached results specified by caller */ + wifi_cached_scan_results *cached_results; +} GScanGetCachedResultsRspParams; + +typedef struct { + int max_channels; + wifi_channel *channels; + int *number_channels; +} GScan_get_valid_channels_cb_data; + +typedef enum{ + eGScanRspParamsInvalid = 0, + eGScanGetValidChannelsRspParams, + eGScanGetCapabilitiesRspParams, + eGScanGetCachedResultsRspParams, +} eGScanRspRarams; + +/* Response and Event Callbacks */ +typedef struct { + /* Various Events Callback */ + void (*on_hotlist_ap_found)(wifi_request_id id, + unsigned num_results, wifi_scan_result *results); + void (*on_hotlist_ap_lost)(wifi_request_id id, + unsigned num_results, wifi_scan_result *results); + void (*on_significant_change)(wifi_request_id id, + unsigned num_results, + wifi_significant_change_result **results); + /* Reported when each probe response is received, if report_events + * enabled in wifi_scan_cmd_params + */ + void (*on_full_scan_result) (wifi_request_id id, wifi_scan_result *result, + unsigned buckets_scanned); + /* Optional event - indicates progress of scanning statemachine */ + void (*on_scan_event) (wifi_request_id id, wifi_scan_event event); + void (*on_hotlist_ssid_found)(wifi_request_id id, + unsigned num_results, wifi_scan_result *results); + void (*on_hotlist_ssid_lost)(wifi_request_id id, + unsigned num_results, wifi_scan_result *results); + void (*on_pno_network_found)(wifi_request_id id, + unsigned num_results, wifi_scan_result *results); + void (*on_passpoint_network_found)(wifi_request_id id, + int net_id, + wifi_scan_result *result, + int anqp_len, + byte *anqp + ); +} GScanCallbackHandler; + +class GScanCommand: public WifiVendorCommand +{ +private: + GScanGetCachedResultsRspParams *mGetCachedResultsRspParams; + GScanCallbackHandler mHandler; + int mRequestId; + int *mChannels; + int mMaxChannels; + int *mNumChannelsPtr; + +public: + GScanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + virtual ~GScanCommand(); + + /* This function implements creation of GSCAN specific Request + * based on the request type. + */ + virtual wifi_error create(); + virtual wifi_error requestResponse(); + virtual int handleResponse(WifiEvent &reply); + virtual void setMaxChannels(int max_channels); + virtual void setChannels(int *channels); + virtual void setNumChannelsPtr(int *num_channels); + virtual wifi_error allocRspParams(eGScanRspRarams cmd); + virtual void freeRspParams(eGScanRspRarams cmd); + virtual wifi_error copyCachedScanResults(int *numResults, + wifi_cached_scan_results *cached_results); + virtual wifi_error gscan_get_cached_results(wifi_cached_scan_results *results, + struct nlattr **tb_vendor); + wifi_error validateGscanConfig(wifi_scan_cmd_params params); + wifi_error validateSignificantChangeParams( + wifi_significant_change_params params); + virtual wifi_error allocCachedResultsTemp(int max, + wifi_cached_scan_results *results); +}; + +#define GSCAN_BASE_PERIOD_MIN 1 +#define GSCAN_MAX_AP_PER_SCAN_MIN 1 +#define GSCAN_REPORT_THRESHOLD_MIN 1 +#define GSCAN_NUM_BUCKETS_MIN 1 +#define GSCAN_BUCKET_INDEX_MIN 0 +#define GSCAN_REPORT_EVENT0 0 +#define GSCAN_REPORT_EVENT1 1 +#define GSCAN_REPORT_EVENT2 2 +#define GSCAN_MIN_CHANNELS 0 +#define GSCAN_ACTIVE_SCAN 0 +#define GSCAN_PASSIVE_SCAN 1 + +#define BSSID_HOTLIST_NUM_AP_MIN 1 + +#define RSSI_SAMPLE_SIZE_MIN 1 +#define LOSTAP_SAMPLE_SIZE_MIN 1 +#define MIN_BREACHING_MIN 1 +#define SIGNIFICANT_CHANGE_NUM_AP_MIN 1 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp new file mode 100644 index 0000000..ef582e0 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp @@ -0,0 +1,914 @@ +/* Copyright (c) 2014, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" +#define LOG_TAG "WifiHAL" +#include <utils/Log.h> +#include <time.h> +#include <errno.h> + +#include "ifaceeventhandler.h" + +/* Used to handle NL command events from driver/firmware. */ +IfaceEventHandlerCommand *mwifiEventHandler = NULL; + +/* Set the interface event monitor handler*/ +wifi_error wifi_set_iface_event_handler(wifi_request_id id, + wifi_interface_handle iface, + wifi_event_handler eh) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + + /* Check if a similar request to set iface event handler was made earlier. + * Right now we don't differentiate between the case where (i) the new + * Request Id is different from the current one vs (ii) both new and + * Request Ids are the same. + */ + if (mwifiEventHandler) + { + if (id == mwifiEventHandler->get_request_id()) { + ALOGE("%s: Iface Event Handler Set for request Id %d is still" + "running. Exit", __func__, id); + return WIFI_ERROR_TOO_MANY_REQUESTS; + } else { + ALOGE("%s: Iface Event Handler Set for a different Request " + "Id:%d is requested. Not supported. Exit", __func__, id); + return WIFI_ERROR_NOT_SUPPORTED; + } + } + + mwifiEventHandler = new IfaceEventHandlerCommand( + wifiHandle, + id, + NL80211_CMD_REG_CHANGE); + if (mwifiEventHandler == NULL) { + ALOGE("%s: Error mwifiEventHandler NULL", __func__); + return WIFI_ERROR_UNKNOWN; + } + mwifiEventHandler->setCallbackHandler(eh); + + return WIFI_SUCCESS; +} + +/* Reset monitoring for the NL event*/ +wifi_error wifi_reset_iface_event_handler(wifi_request_id id, + wifi_interface_handle iface) +{ + if (mwifiEventHandler) + { + if (id == mwifiEventHandler->get_request_id()) { + ALOGV("Delete Object mwifiEventHandler for id = %d", id); + delete mwifiEventHandler; + mwifiEventHandler = NULL; + } else { + ALOGE("%s: Iface Event Handler Set for a different Request " + "Id:%d is requested. Not supported. Exit", __func__, id); + return WIFI_ERROR_NOT_SUPPORTED; + } + } else { + ALOGV("Object mwifiEventHandler for id = %d already Deleted", id); + } + + return WIFI_SUCCESS; +} + +/* This function will be the main handler for the registered incoming + * (from driver) Commads. Calls the appropriate callback handler after + * parsing the vendor data. + */ +int IfaceEventHandlerCommand::handleEvent(WifiEvent &event) +{ + wifiEventHandler::handleEvent(event); + + switch(mSubcmd) + { + case NL80211_CMD_REG_CHANGE: + { + char code[2]; + memset(&code[0], 0, 2); + if(tb[NL80211_ATTR_REG_ALPHA2]) + { + memcpy(&code[0], (char *) nla_data(tb[NL80211_ATTR_REG_ALPHA2]), 2); + } else { + ALOGE("%s: NL80211_ATTR_REG_ALPHA2 not found", __func__); + } + ALOGV("Country : %c%c", code[0], code[1]); + if(mHandler.on_country_code_changed) + { + mHandler.on_country_code_changed(code); + } + } + break; + default: + ALOGV("NL Event : %d Not supported", mSubcmd); + } + + return NL_SKIP; +} + +IfaceEventHandlerCommand::IfaceEventHandlerCommand(wifi_handle handle, int id, u32 subcmd) + : wifiEventHandler(handle, id, subcmd) +{ + ALOGV("wifiEventHandler %p constructed", this); + registerHandler(mSubcmd); + memset(&mHandler, 0, sizeof(wifi_event_handler)); + mEventData = NULL; + mDataLen = 0; +} + +IfaceEventHandlerCommand::~IfaceEventHandlerCommand() +{ + ALOGV("IfaceEventHandlerCommand %p destructor", this); + unregisterHandler(mSubcmd); +} + +void IfaceEventHandlerCommand::setCallbackHandler(wifi_event_handler nHandler) +{ + mHandler = nHandler; +} + +int wifiEventHandler::get_request_id() +{ + return mRequestId; +} + +int IfaceEventHandlerCommand::get_request_id() +{ + return wifiEventHandler::get_request_id(); +} + +wifiEventHandler::wifiEventHandler(wifi_handle handle, int id, u32 subcmd) + : WifiCommand(handle, id) +{ + mRequestId = id; + mSubcmd = subcmd; + registerHandler(mSubcmd); + ALOGV("wifiEventHandler %p constructed", this); +} + +wifiEventHandler::~wifiEventHandler() +{ + ALOGV("wifiEventHandler %p destructor", this); + unregisterHandler(mSubcmd); +} + +int wifiEventHandler::handleEvent(WifiEvent &event) +{ + struct genlmsghdr *gnlh = event.header(); + mSubcmd = gnlh->cmd; + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + ALOGV("Got NL Event : %d from the Driver.", gnlh->cmd); + + return NL_SKIP; +} + +WifihalGeneric::WifihalGeneric(wifi_handle handle, int id, u32 vendor_id, + u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + hal_info *info = getHalInfo(handle); + + /* Initialize the member data variables here */ + mSet = 0; + mSetSizeMax = 0; + mSetSizePtr = NULL; + mConcurrencySet = 0; + filterVersion = 0; + filterLength = 0; + firmware_bus_max_size = 0; + mCapa = &(info->capa); + mfilter_packet_read_buffer = NULL; + mfilter_packet_length = 0; + res_size = 0; + channel_buff = NULL; + memset(&mDriverFeatures, 0, sizeof(mDriverFeatures)); + memset(&mRadarResultParams, 0, sizeof(RadarHistoryResultsParams)); +} + +WifihalGeneric::~WifihalGeneric() +{ + mCapa = NULL; + if (mDriverFeatures.flags != NULL) { + free(mDriverFeatures.flags); + mDriverFeatures.flags = NULL; + } +} + +wifi_error WifihalGeneric::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +static u32 get_wifi_iftype_masks(u32 in_mask) +{ + u32 op_mask = 0; + + if (in_mask & BIT(NL80211_IFTYPE_STATION)) { + op_mask |= BIT(WIFI_INTERFACE_STA); + op_mask |= BIT(WIFI_INTERFACE_TDLS); + } + if (in_mask & BIT(NL80211_IFTYPE_AP)) + op_mask |= BIT(WIFI_INTERFACE_SOFTAP); + if (in_mask & BIT(NL80211_IFTYPE_P2P_CLIENT)) + op_mask |= BIT(WIFI_INTERFACE_P2P_CLIENT); + if (in_mask & BIT(NL80211_IFTYPE_P2P_GO)) + op_mask |= BIT(WIFI_INTERFACE_P2P_GO); + if (in_mask & BIT(NL80211_IFTYPE_NAN)) + op_mask |= BIT(WIFI_INTERFACE_NAN); + + return op_mask; +} + +static wifi_channel_width get_channel_width(u32 nl_width) +{ + switch(nl_width) { + case NL80211_CHAN_WIDTH_20: + return WIFI_CHAN_WIDTH_20; + case NL80211_CHAN_WIDTH_40: + return WIFI_CHAN_WIDTH_40; + case NL80211_CHAN_WIDTH_80: + return WIFI_CHAN_WIDTH_80; + case NL80211_CHAN_WIDTH_160: + return WIFI_CHAN_WIDTH_160; + case NL80211_CHAN_WIDTH_80P80: + return WIFI_CHAN_WIDTH_80P80; + case NL80211_CHAN_WIDTH_5: + return WIFI_CHAN_WIDTH_5; + case NL80211_CHAN_WIDTH_10: + return WIFI_CHAN_WIDTH_10; + default: + return WIFI_CHAN_WIDTH_INVALID; + } +} + +int WifihalGeneric::handle_response_usable_channels(struct nlattr *VendorData, + u32 mDataLen) +{ + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX + 1]; + struct nlattr *curr_attr; + wifi_usable_channel *chan_info = NULL; + int rem; + u32 currSize = 0; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL)) { + ALOGE("Failed to parse NL channels list"); + return WIFI_ERROR_INVALID_ARGS; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO]) { + ALOGE("%s: USABLE_CHANNELS_CHAN_INFO not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + for_each_nested_attribute(curr_attr, + tb[QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO], rem) { + struct nlattr *ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX + 1]; + + if (currSize >= mSetSizeMax) { + ALOGE("Got max channels %d completed", mSetSizeMax); + break; + } + + if (nla_parse_nested(ch_info, QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX, + curr_attr, NULL)) { + ALOGE("Failed to get usable channel info"); + return NL_SKIP; + } + + chan_info = &channel_buff[currSize]; + if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]) { + ALOGE("%s: CHAN_INFO_PRIMARY_FREQ not found", + __FUNCTION__); + return NL_SKIP; + } + + chan_info->freq = nla_get_u32(ch_info[ + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ]); + if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH]) { + ALOGE("%s: CHAN_INFO_BANDWIDTH not found", + __FUNCTION__); + return NL_SKIP; + } + + chan_info->width = get_channel_width(nla_get_u32( + ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH])); + if (!ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK]) { + ALOGE("%s: CHAN_INFO_IFACE_MODE_MASK not found", + __FUNCTION__); + return NL_SKIP; + } + + chan_info->iface_mode_mask = get_wifi_iftype_masks(nla_get_u32( + ch_info[QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK])); + ALOGV("Primary freq %d BW %d iface mask %d", chan_info->freq, + chan_info->width, chan_info->iface_mode_mask); + currSize++; + } + + res_size = currSize; + ALOGV("%s: Result size %d", __FUNCTION__, res_size); + + return NL_SKIP; +} + +int WifihalGeneric::handleResponse(WifiEvent &reply) +{ + ALOGV("Got a Wi-Fi HAL module message from Driver"); + int i = 0; + WifiVendorCommand::handleResponse(reply); + + // Parse the vendordata and get the attribute + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES: + { + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_FEATURE_SET_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_FEATURE_SET not found", __func__); + return -EINVAL; + } + mSet = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_SET]); + ALOGV("Supported feature set : %" PRIx64, mSet); + + break; + } + case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: + { + struct nlattr *attr; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS]; + if (attr) { + int len = nla_len(attr); + mDriverFeatures.flags = (u8 *)malloc(len); + if (mDriverFeatures.flags != NULL) { + memcpy(mDriverFeatures.flags, nla_data(attr), len); + mDriverFeatures.flags_len = len; + } + } + break; + } + case QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX: + { + struct nlattr *tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1]; + nla_parse(tb_vendor, + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX, + (struct nlattr *)mVendorData,mDataLen, NULL); + + if (tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]) { + u32 val; + val = nla_get_u32( + tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE]); + + ALOGV("%s: Num of concurrency combinations: %d", + __func__, val); + val = val > (unsigned int)mSetSizeMax ? + (unsigned int)mSetSizeMax : val; + *mSetSizePtr = val; + + /* Extract the list of channels. */ + if (*mSetSizePtr > 0 && + tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET]) { + nla_memcpy(mConcurrencySet, + tb_vendor[ + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET], + sizeof(feature_set) * (*mSetSizePtr)); + } + + ALOGV("%s: Get concurrency matrix response received.", + __func__); + ALOGV("%s: Num of concurrency combinations : %d", + __func__, *mSetSizePtr); + ALOGV("%s: List of valid concurrency combinations is: ", + __func__); + for(i = 0; i < *mSetSizePtr; i++) + { + ALOGV("%" PRIx64, *(mConcurrencySet + i)); + } + } + } + break; + case QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER: + { + int subCmd; + struct nlattr *tb_vendor[ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD]) + { + subCmd = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD]); + } else { + /* + * The older drivers may not send PACKET_FILTER_SUB_CMD as + * they support QCA_WLAN_GET_PACKET_FILTER only. + */ + subCmd = QCA_WLAN_GET_PACKET_FILTER; + } + if (subCmd == QCA_WLAN_GET_PACKET_FILTER) { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION" + " not found", __FUNCTION__); + return -EINVAL; + } + filterVersion = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION]); + ALOGV("Current version : %u", filterVersion); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE" + " not found", __FUNCTION__); + return -EINVAL; + } + filterLength = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE]); + ALOGV("Max filter length Supported : %u", filterLength); + } else if (subCmd == QCA_WLAN_READ_PACKET_FILTER) { + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM" + " not found", __FUNCTION__); + return -EINVAL; + } + if (nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]) + < mfilter_packet_length) + { + ALOGE("%s: Expected packet filter length :%d but received only: %d bytes", + __FUNCTION__, mfilter_packet_length, + nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM])); + return -EINVAL; + } + memcpy(mfilter_packet_read_buffer, + nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM]), + mfilter_packet_length); + ALOGV("Filter Program length : %u", mfilter_packet_length); + } else { + ALOGE("%s: Unknown APF sub command received", + __FUNCTION__); + return -EINVAL; + } + + } + break; + case QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE: + { + struct nlattr *tb_vendor[ + QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE" + " not found", __FUNCTION__); + return -EINVAL; + } + firmware_bus_max_size = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE]); + ALOGV("Max BUS size Supported: %d", firmware_bus_max_size); + } + break; + case QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES: + { + struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX + 1]; + nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX, + (struct nlattr *)mVendorData,mDataLen, NULL); + + if (wifiParseCapabilities(tbVendor) == WIFI_SUCCESS) { + ALOGV("%s: GSCAN Capabilities:\n" + " max_ap_cache_per_scan:%d\n" + " max_bssid_history_entries:%d\n" + " max_hotlist_bssids:%d\n" + " max_hotlist_ssids:%d\n" + " max_rssi_sample_size:%d\n" + " max_scan_buckets:%d\n" + " max_scan_cache_size:%d\n" + " max_scan_reporting_threshold:%d\n" + " max_significant_wifi_change_aps:%d\n" + " max_number_epno_networks:%d\n" + " max_number_epno_networks_by_ssid:%d\n" + " max_number_of_white_listed_ssid:%d.", + __FUNCTION__, mCapa->gscan_capa.max_ap_cache_per_scan, + mCapa->gscan_capa.max_bssid_history_entries, + mCapa->gscan_capa.max_hotlist_bssids, + mCapa->gscan_capa.max_hotlist_ssids, + mCapa->gscan_capa.max_rssi_sample_size, + mCapa->gscan_capa.max_scan_buckets, + mCapa->gscan_capa.max_scan_cache_size, + mCapa->gscan_capa.max_scan_reporting_threshold, + mCapa->gscan_capa.max_significant_wifi_change_aps, + mCapa->gscan_capa.max_number_epno_networks, + mCapa->gscan_capa.max_number_epno_networks_by_ssid, + mCapa->gscan_capa.max_number_of_white_listed_ssid); + + ALOGV("%s: Roaming Capabilities:\n" + " max_blacklist_size: %d\n" + " max_whitelist_size: %d\n", + __FUNCTION__, mCapa->roaming_capa.max_blacklist_size, + mCapa->roaming_capa.max_whitelist_size); + } + } + break; + case QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: + return handle_response_usable_channels((struct nlattr *)mVendorData, + mDataLen); + case QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: + { + wifiParseRadarHistory(); + } + break; + default : + ALOGE("%s: Wrong Wi-Fi HAL event received %d", __func__, mSubcmd); + } + return NL_SKIP; +} + +/* Parses and extract capabilities results. */ +wifi_error WifihalGeneric::wifiParseCapabilities(struct nlattr **tbVendor) +{ + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_scan_cache_size = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_scan_buckets = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_ap_cache_per_scan = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_rssi_sample_size = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD not" + " found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_scan_reporting_threshold = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_hotlist_bssids = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS] + ) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS " + "not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_significant_wifi_change_aps = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES not " + "found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mCapa->gscan_capa.max_bssid_history_entries = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS not found. Set" + " to 0.", __FUNCTION__); + mCapa->gscan_capa.max_hotlist_ssids = 0; + } else { + mCapa->gscan_capa.max_hotlist_ssids = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS]); + } + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS not found. Set" + " to 0.", __FUNCTION__); + mCapa->gscan_capa.max_number_epno_networks = 0; + } else { + mCapa->gscan_capa.max_number_epno_networks + = nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS + ]); + } + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID not " + "found. Set to 0.", __FUNCTION__); + mCapa->gscan_capa.max_number_epno_networks_by_ssid = 0; + } else { + mCapa->gscan_capa.max_number_epno_networks_by_ssid = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID]); + } + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID not " + "found. Set to 0.", __FUNCTION__); + mCapa->gscan_capa.max_number_of_white_listed_ssid = 0; + mCapa->roaming_capa.max_whitelist_size = 0; + } else { + mCapa->gscan_capa.max_number_of_white_listed_ssid = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID]); + mCapa->roaming_capa.max_whitelist_size = mCapa->gscan_capa.max_number_of_white_listed_ssid; + } + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX" + "_NUM_BLACKLIST_BSSID not found. Set to 0.", __FUNCTION__); + mCapa->roaming_capa.max_blacklist_size = 0; + } else { + mCapa->roaming_capa.max_blacklist_size = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID]); + } + return WIFI_SUCCESS; +} + +wifi_error WifihalGeneric::wifiParseRadarHistory() { +{ + // tbVendor + struct nlattr *tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1]; + int rem = 0, num_dfs_entries = 0; + + if (nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX, + (struct nlattr *)mVendorData,mDataLen, NULL)) { + ALOGE("%s: nla_parse fail", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES]) { + ALOGE("%s: radar attr entries not present", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + // nested radar history + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1]; + struct nlattr *attr; + static struct nla_policy + policy[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ] = { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP] = { .type = NLA_U64 }, + [QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED] = { .type = NLA_FLAG }, + }; + radar_history_result *newEntry; + radar_history_result *temp; + u32 totalEntrySize = 0; + u32 newEntrySize = sizeof(radar_history_result); + + nla_for_each_nested(attr, + tbVendor[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES], + rem) { + if ((num_dfs_entries ++) > MAX_NUM_RADAR_HISTORY) { + ALOGE("%s: exceeded max entries, drop others", __FUNCTION__); + break; + } + if (nla_parse_nested(tb, QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX, + attr, policy)) { + ALOGI("%s: nla_parse_nested fail", __FUNCTION__); + continue; + } + if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]) { + ALOGI("%s: radar attr freq not present", __FUNCTION__); + continue; + } + if (!tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]) { + ALOGI("%s: radar attr timestamp not present", __FUNCTION__); + continue; + } + + // realloc buffer for new entry + temp = (radar_history_result *) realloc( + mRadarResultParams.entries, totalEntrySize + newEntrySize); + if (temp == NULL) { + ALOGE("%s: failed to realloc memory", __FUNCTION__); + free(mRadarResultParams.entries); + mRadarResultParams.entries = NULL; + return WIFI_ERROR_OUT_OF_MEMORY; + } + mRadarResultParams.entries = temp; + + newEntry = (radar_history_result *)( + (u8 *) mRadarResultParams.entries + totalEntrySize); + memset(newEntry, 0, newEntrySize); + totalEntrySize += newEntrySize; + + // save to current radar entry + newEntry->freq = nla_get_u32( + tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ]); + newEntry->clock_boottime = nla_get_u64( + tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP]); + newEntry->radar_detected = false; + if (tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]) { + newEntry->radar_detected = nla_get_flag( + tb[QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED]); + } + mRadarResultParams.num_entries ++; + + ALOGI("Radar history: freq:%d boottime: %" PRId64 " detected:%d", + newEntry->freq, + newEntry->clock_boottime, + newEntry->radar_detected); + } + } + + return WIFI_SUCCESS; +} + + +void WifihalGeneric::getResponseparams(feature_set *pset) +{ + *pset = mSet; +} + +void WifihalGeneric::getDriverFeatures(features_info *pfeatures) +{ + if (!pfeatures) + return; + + if (mDriverFeatures.flags != NULL) { + pfeatures->flags = (u8 *)malloc(mDriverFeatures.flags_len); + if (pfeatures->flags) { + memcpy(pfeatures->flags, mDriverFeatures.flags, + mDriverFeatures.flags_len); + pfeatures->flags_len = mDriverFeatures.flags_len; + return; + } + } + + pfeatures->flags_len = 0; + pfeatures->flags = NULL; +} + +void WifihalGeneric::setMaxSetSize(int set_size_max) { + mSetSizeMax = set_size_max; +} + +void WifihalGeneric::setConcurrencySet(feature_set set[]) { + mConcurrencySet = set; +} + +void WifihalGeneric::setSizePtr(int *set_size) { + mSetSizePtr = set_size; +} + +int WifihalGeneric::getFilterVersion() { + return filterVersion; +} + +int WifihalGeneric::getFilterLength() { + return filterLength; +} +void WifihalGeneric::setPacketBufferParams(u8 *host_packet_buffer, int packet_length) { + mfilter_packet_read_buffer = host_packet_buffer; + mfilter_packet_length = packet_length; +} + +int WifihalGeneric::getBusSize() { + return firmware_bus_max_size; +} + +void WifihalGeneric::set_channels_buff(wifi_usable_channel* channels) +{ + channel_buff = channels; + memset(channel_buff, 0, sizeof(wifi_usable_channel) * mSetSizeMax); +} + +u32 WifihalGeneric::get_results_size(void) +{ + return res_size; +} + +wifi_error WifihalGeneric::wifiGetCapabilities(wifi_interface_handle handle) +{ + wifi_error ret; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(handle); + + /* Create the NL message. */ + ret = create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create NL message, Error:%d", __FUNCTION__, ret); + return ret; + } + + /* Set the interface Id of the message. */ + ret = set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set interface Id of message, Error:%d", __FUNCTION__, ret); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + return WIFI_ERROR_OUT_OF_MEMORY; + + ret = put_u32(QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID, mId); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to add request_ID to NL command, Error:%d", __FUNCTION__, ret); + return ret; + } + + attr_end(nlData); + + ret = requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret); + + return ret; +} + +wifi_error WifihalGeneric::copyCachedRadarHistory( + radar_history_result *resultBuf, int resultBufSize, int *numResults) { + *numResults = 0; + + if (mRadarResultParams.entries) { + radar_history_result *sEntry = NULL; + radar_history_result *tEntry = NULL; + u32 offset = 0; + int i; + + for (i = 0; i < mRadarResultParams.num_entries; i ++) { + if (resultBufSize < (offset + sizeof(radar_history_result))) { + break; + } + + sEntry = (radar_history_result *)( + (u8 *) mRadarResultParams.entries + offset); + tEntry = (radar_history_result *)( + (u8 *) resultBuf + offset); + memcpy(tEntry, sEntry, sizeof(radar_history_result)); + (*numResults) += 1; + offset += sizeof(radar_history_result); + } + } + + return WIFI_SUCCESS; +} + +void WifihalGeneric::freeCachedRadarHistory() { + if (mRadarResultParams.entries) { + free(mRadarResultParams.entries); + mRadarResultParams.entries = NULL; + mRadarResultParams.num_entries = 0; + } +} diff --git a/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h new file mode 100644 index 0000000..f0b681a --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h @@ -0,0 +1,143 @@ +/* Copyright (c) 2014, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_IFACEEVENTHANDLER_COMMAND_H__ +#define __WIFI_HAL_IFACEEVENTHANDLER_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif +#include "vendor_definitions.h" +#include "wifi_hal.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct{ + int num_entries; + radar_history_result *entries; +} RadarHistoryResultsParams; + +class wifiEventHandler: public WifiCommand +{ +private: + int mRequestId; + +protected: + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + u32 mSubcmd; + +public: + wifiEventHandler(wifi_handle handle, int id, u32 subcmd); + virtual ~wifiEventHandler(); + virtual int get_request_id(); + virtual int handleEvent(WifiEvent &event); +}; + +class IfaceEventHandlerCommand: public wifiEventHandler +{ +private: + char *mEventData; + u32 mDataLen; + wifi_event_handler mHandler; + +public: + IfaceEventHandlerCommand(wifi_handle handle, int id, u32 subcmd); + virtual ~IfaceEventHandlerCommand(); + + virtual int handleEvent(WifiEvent &event); + virtual void setCallbackHandler(wifi_event_handler nHandler); + virtual int get_request_id(); +}; + +class WifihalGeneric: public WifiVendorCommand +{ +private: + feature_set mSet; + features_info mDriverFeatures; + int mSetSizeMax; + int *mSetSizePtr; + feature_set *mConcurrencySet; + int filterVersion; + int filterLength; + int firmware_bus_max_size; + wifi_capa *mCapa; + /* Packet Filter buffer and length */ + u8 *mfilter_packet_read_buffer; + int mfilter_packet_length; + u32 res_size; + wifi_usable_channel *channel_buff; + RadarHistoryResultsParams mRadarResultParams; + virtual wifi_error wifiParseCapabilities(struct nlattr **tbVendor); + virtual wifi_error wifiParseRadarHistory(); + +public: + WifihalGeneric(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + virtual ~WifihalGeneric(); + virtual wifi_error requestResponse(); + virtual int handleResponse(WifiEvent &reply); + virtual int handle_response_usable_channels(struct nlattr *VendorData, + u32 mDataLen); + virtual void getResponseparams(feature_set *pset); + virtual void getDriverFeatures(features_info *pfeatures); + virtual void setMaxSetSize(int set_size_max); + virtual void setSizePtr(int *set_size); + virtual void setPacketBufferParams(u8 *host_packet_buffer, int packet_length); + virtual void setConcurrencySet(feature_set set[]); + virtual int getFilterVersion(); + virtual int getFilterLength(); + virtual int getBusSize(); + virtual wifi_error wifiGetCapabilities(wifi_interface_handle handle); + virtual void set_channels_buff(wifi_usable_channel *channels); + virtual u32 get_results_size(void); + virtual wifi_error copyCachedRadarHistory(radar_history_result *resultBuf, + int resultBufSize, int *numResults); + virtual void freeCachedRadarHistory(); +}; + +/** + * nla_for_each_nested from libnl is throwing implicit conversion from void* + * error. Adding a local definition to avoid it. + */ +#define for_each_nested_attribute(pos, nla, rem) \ + for (pos = (struct nlattr *)nla_data(nla), rem = nla_len(nla); \ + nla_ok(pos, rem); \ + pos = nla_next(pos, &(rem))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/list.cpp b/wcn6740/qcwcn/wifi_hal/list.cpp new file mode 100644 index 0000000..966da2e --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/list.cpp @@ -0,0 +1,76 @@ +/* Copyright (c) 2019 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include <stdlib.h> +#include "list.h" + +void INITIALISE_LIST(struct list_head *list) +{ + list->next = list; + list->prev = list; +} + +void list_add(struct list_head *latest, + struct list_head *prev, struct list_head *next) +{ + next->prev = latest; + latest->next = next; + latest->prev = prev; + prev->next = latest; +} + +void add_to_list(struct list_head *latest, struct list_head *head) +{ + list_add(latest, head, head->next); +} + +void list_add_tail(struct list_head *latest, struct list_head *head) +{ + list_add(latest, head->prev, head); +} + +void list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +void del_from_list(struct list_head *record) +{ + list_del(record->prev, record->next); + record->next = NULL; + record->prev = NULL; +} + +void replace_in_list(struct list_head *old, struct list_head *latest) +{ + latest->next = old->next; + latest->next->prev = latest; + latest->prev = old->prev; + latest->prev->next = latest; +} diff --git a/wcn6740/qcwcn/wifi_hal/list.h b/wcn6740/qcwcn/wifi_hal/list.h new file mode 100644 index 0000000..90d344c --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/list.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2019 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef _WIFIHAL_LIST_H_ +#define _WIFIHAL_LIST_H_ + +struct list_head { + struct list_head *next, *prev; +}; + +void INITIALISE_LIST(struct list_head *list); +void list_add(struct list_head *latest, struct list_head *prev, + struct list_head *next); +void add_to_list(struct list_head *latest, struct list_head *head); +void list_add_tail(struct list_head *latest, struct list_head *head); +void list_del(struct list_head *prev, struct list_head *next); +void del_from_list(struct list_head *record); +void replace_in_list(struct list_head *old, struct list_head *latest); + +#define list_for_each(ref, head) \ + for (ref = (head)->next; ref->next, ref != (head); ref = ref->next) + +#define offset_of(type, member) ((char *)&((type *)0)->member) + +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offset_of(type, member)); }) + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_for_each_entry(ref, head, member) \ + for (ref = list_entry((head)->next, typeof(*ref), member); \ + ref->member.next, &ref->member != (head); \ + ref = list_entry(ref->member.next, typeof(*ref), member)) + +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) + +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +#endif diff --git a/wcn6740/qcwcn/wifi_hal/llstats.cpp b/wcn6740/qcwcn/wifi_hal/llstats.cpp new file mode 100644 index 0000000..3779b58 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/llstats.cpp @@ -0,0 +1,1472 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "llstatscommand.h" + +//Singleton Static Instance +LLStatsCommand* LLStatsCommand::mLLStatsCommandInstance = NULL; + +// This function implements creation of Vendor command +// For LLStats just call base Vendor command create +wifi_error LLStatsCommand::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + // insert the oui in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + return ret; + + // insert the subcmd in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + + return ret; +} + +LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mClearRspParams, 0,sizeof(LLStatsClearRspParams)); + memset(&mResultsParams, 0,sizeof(LLStatsResultsParams)); + memset(&mHandler, 0,sizeof(mHandler)); + mRadioStatsSize = 0; + mNumRadios = 0; + mNumRadiosAllocated = 0; +} + +LLStatsCommand::~LLStatsCommand() +{ + mLLStatsCommandInstance = NULL; +} + +LLStatsCommand* LLStatsCommand::instance(wifi_handle handle) +{ + if (handle == NULL) { + ALOGE("Interface Handle is invalid"); + return NULL; + } + if (mLLStatsCommandInstance == NULL) { + mLLStatsCommandInstance = new LLStatsCommand(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET); + return mLLStatsCommandInstance; + } + else + { + if (handle != getWifiHandle(mLLStatsCommandInstance->mInfo)) + { + /* upper layer must have cleaned up the handle and reinitialized, + so we need to update the same */ + ALOGE("Handle different, update the handle"); + mLLStatsCommandInstance->mInfo = (hal_info *)handle; + } + } + return mLLStatsCommandInstance; +} + +void LLStatsCommand::initGetContext(u32 reqId) +{ + mRequestId = reqId; + memset(&mHandler, 0,sizeof(mHandler)); +} + +void LLStatsCommand::setSubCmd(u32 subcmd) +{ + mSubcmd = subcmd; +} + +void LLStatsCommand::setHandler(wifi_stats_result_handler handler) +{ + mHandler = handler; +} + +static wifi_error get_wifi_interface_info(wifi_interface_link_layer_info *stats, + struct nlattr **tb_vendor) +{ + u32 len = 0; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mode = (wifi_interface_mode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE]); + + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]); + len = ((sizeof(stats->mac_addr) <= len) ? sizeof(stats->mac_addr) : len); + memcpy(&stats->mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]), len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->state = (wifi_connection_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->roaming = (wifi_roam_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->capabilities = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]); + len = ((sizeof(stats->ssid) <= len) ? sizeof(stats->ssid) : len); + memcpy(&stats->ssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]), len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]); + len = ((sizeof(stats->bssid) <= len) ? sizeof(stats->bssid) : len); + memcpy(&stats->bssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]), len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]); + len = ((sizeof(stats->ap_country_str) <= len) ? sizeof(stats->ap_country_str) : len); + memcpy(&stats->ap_country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]), + len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]); + len = ((sizeof(stats->country_str) < len) ? sizeof(stats->country_str) : len); + memcpy(&stats->country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]), + len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->time_slicing_duty_cycle_percent = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE]); +#if QC_HAL_DEBUG + ALOGV("Mode : %d\n" + "Mac addr : " + MAC_ADDR_STR + "\nState : %d\n" + "Roaming : %d\n" + "capabilities : %0x\n" + "SSID :%s\n" + "BSSID : " + MAC_ADDR_STR + "\nAP country str : %c%c%c\n" + "Country String for this Association : %c%c%c\n" + "Time slicing duty cycle : %d", + stats->mode, + MAC_ADDR_ARRAY(stats->mac_addr), + stats->state, + stats->roaming, + stats->capabilities, + stats->ssid, + MAC_ADDR_ARRAY(stats->bssid), + stats->ap_country_str[0], + stats->ap_country_str[1], + stats->ap_country_str[2], + stats->country_str[0], + stats->country_str[1], + stats->country_str[2], + stats->time_slicing_duty_cycle_percent); +#endif + return WIFI_SUCCESS; +} + +static wifi_error get_wifi_wmm_ac_stat(wifi_wmm_ac_stat *stats, + struct nlattr **tb_vendor) +{ + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->ac = (wifi_traffic_ac)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_mcast = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rx_mcast = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rx_ampdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_ampdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mpdu_lost = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries_short = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries_long = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->contention_time_min = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->contention_time_max = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->contention_time_avg = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->contention_num_samples = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]); +#ifdef QC_HAL_DEBUG + ALOGV("%4u | %6u | %6u | %7u | %7u | %7u |" + " %7u | %8u | %7u | %12u |" + " %11u | %17u | %17u |" + " %17u | %20u", + stats->ac, + stats->tx_mpdu, + stats->rx_mpdu, + stats->tx_mcast, + stats->rx_mcast, + stats->rx_ampdu, + stats->tx_ampdu, + stats->mpdu_lost, + stats->retries, + stats->retries_short, + stats->retries_long, + stats->contention_time_min, + stats->contention_time_max, + stats->contention_time_avg, + stats->contention_num_samples); +#endif + return WIFI_SUCCESS; +} + +static wifi_error get_wifi_rate_stat(wifi_rate_stat *stats, + struct nlattr **tb_vendor) +{ + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rate.preamble = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rate.nss = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rate.bw = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rate.rateMcsIdx = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rate.bitrate = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rx_mpdu = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mpdu_lost = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries_short = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->retries_long = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG]); +#ifdef QC_HAL_DEBUG + ALOGV("%8u | %3u | %2u | %10u | %7u | %6u | %6u | %8u | %7u | %12u | %11u", + stats->rate.preamble, + stats->rate.nss, + stats->rate.bw, + stats->rate.rateMcsIdx, + stats->rate.bitrate, + stats->tx_mpdu, + stats->rx_mpdu, + stats->mpdu_lost, + stats->retries, + stats->retries_short, + stats->retries_long); +#endif + return WIFI_SUCCESS; +} + +static wifi_error get_wifi_peer_info(wifi_peer_info *stats, + struct nlattr **tb_vendor) +{ + u32 i = 0, len = 0; + int rem; + wifi_rate_stat * pRateStats; + struct nlattr *rateInfo; + wifi_error ret = WIFI_SUCCESS; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->type = (wifi_peer_type)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]); + len = ((sizeof(stats->peer_mac_address) <= len) ? sizeof(stats->peer_mac_address) : len); + memcpy((void *)&stats->peer_mac_address[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]), + len); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->capabilities = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->num_rate = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]); +#ifdef QC_HAL_DEBUG + ALOGV("numPeers %u Peer MAC addr :" MAC_ADDR_STR " capabilities %0x numRate %u", + stats->type, MAC_ADDR_ARRAY(stats->peer_mac_address), + stats->capabilities, stats->num_rate); +#endif + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } +#ifdef QC_HAL_DEBUG + ALOGV("%8s | %3s | %2s | %10s | %7s | %6s | %6s | %8s | %7s | %12s | %11s", + "preamble", "nss", "bw", "rateMcsIdx", "bitrate", "txMpdu", "rxMpdu", "mpduLost", "retries", "retriesShort", "retriesLong"); +#endif + for (rateInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]); + nla_ok(rateInfo, rem); + rateInfo = nla_next(rateInfo, &(rem))) + { + struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; + pRateStats = (wifi_rate_stat *) ((u8 *)stats->rate_stats + (i++ * sizeof(wifi_rate_stat))); + + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(rateInfo), nla_len(rateInfo), NULL); + ret = get_wifi_rate_stat(pRateStats, tb2); + if(ret != WIFI_SUCCESS) + { + return ret; + } + } + return WIFI_SUCCESS; +} + +wifi_error LLStatsCommand::get_wifi_iface_stats(wifi_iface_stat *stats, + struct nlattr **tb_vendor) +{ + struct nlattr *wmmInfo; + wifi_wmm_ac_stat *pWmmStats; + int i=0, rem; + wifi_error ret = WIFI_SUCCESS; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX" + "not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->beacon_rx = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET]) + { + stats->average_tsf_offset = 0; + } else { + stats->average_tsf_offset = nla_get_u64(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET]); + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED]) + { + stats->leaky_ap_detected = 0; + } else { + stats->leaky_ap_detected = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED]); + } + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED]) + { + stats->leaky_ap_avg_num_frames_leaked = 0; + } else { + stats->leaky_ap_avg_num_frames_leaked = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED]); + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME]) + { + stats->leaky_ap_guard_time = 0; + } else { + stats->leaky_ap_guard_time = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME]); + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mgmt_rx = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX]); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX]) + { + ALOGE("%s: " + "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mgmt_action_rx = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX]); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX]) + { + ALOGE("%s: " + "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->mgmt_action_tx = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rssi_mgmt = get_s32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rssi_data = get_s32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rssi_ack = get_s32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK]); +#ifdef QC_HAL_DEBUG + ALOGV("WMM STATS"); + ALOGV("beaconRx : %u " + "mgmtRx : %u " + "mgmtActionRx : %u " + "mgmtActionTx : %u " + "rssiMgmt : %d " + "rssiData : %d " + "rssiAck : %d ", + stats->beacon_rx, + stats->mgmt_rx, + stats->mgmt_action_rx, + stats->mgmt_action_tx, + stats->rssi_mgmt, + stats->rssi_data, + stats->rssi_ack); +#endif + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } +#ifdef QC_HAL_DEBUG + ALOGV("%4s | %6s | %6s | %7s | %7s | %7s |" + " %7s | %8s | %7s | %12s |" + " %11s | %17s | %17s |" + " %17s | %20s", + "ac","txMpdu", "rxMpdu", "txMcast", "rxMcast", "rxAmpdu", + "txAmpdu", "mpduLost", "retries", "retriesShort", + "retriesLong", "contentionTimeMin", "contentionTimeMax", + "contentionTimeAvg", "contentionNumSamples"); +#endif + for (wmmInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]); + nla_ok(wmmInfo, rem); + wmmInfo = nla_next(wmmInfo, &(rem))) + { + struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; + pWmmStats = (wifi_wmm_ac_stat *) ((u8 *)stats->ac + + (i++ * sizeof(wifi_wmm_ac_stat))); + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, + (struct nlattr *) nla_data(wmmInfo), + nla_len(wmmInfo), NULL); + ret = get_wifi_wmm_ac_stat(pWmmStats, tb2); + if(ret != WIFI_SUCCESS) + { + return ret; + } + } + + return WIFI_SUCCESS; +} + +static wifi_error get_wifi_radio_stats(wifi_radio_stat *stats, + struct nlattr **tb_vendor) +{ + u32 i = 0; + struct nlattr *chInfo; + wifi_channel_stat *pChStats; + int rem; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->radio = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME]); + + if (stats->num_tx_levels) { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL]) { + ALOGE("%s: num_tx_levels is %u but QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL not found", __func__, stats->num_tx_levels); + stats->num_tx_levels = 0; + return WIFI_ERROR_INVALID_ARGS; + } + stats->tx_time_per_levels = + (u32 *) malloc(sizeof(u32) * stats->num_tx_levels); + if (!stats->tx_time_per_levels) { + ALOGE("%s: radio_stat: tx_time_per_levels malloc Failed", __func__); + stats->num_tx_levels = 0; + return WIFI_ERROR_OUT_OF_MEMORY; + } + + nla_memcpy(stats->tx_time_per_levels, + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL], + sizeof(u32) * stats->num_tx_levels); + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->rx_time = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_nbd = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_gscan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_roam_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_pno_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20 not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->on_time_hs20 = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20]); + + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + stats->num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]); + + if (stats->num_channels == 0) { + return WIFI_SUCCESS; + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + for (chInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]); + nla_ok(chInfo, rem); + chInfo = nla_next(chInfo, &(rem))) + { + struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; + pChStats = (wifi_channel_stat *) ((u8 *)stats->channels + (i++ * (sizeof(wifi_channel_stat)))); + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->channel.width = (wifi_channel_width)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->channel.center_freq = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0 not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->channel.center_freq0 = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1 not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->channel.center_freq1 = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->on_time = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME]); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChStats->cca_busy_time = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME]); + + if (tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME] && + nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME]) <= pChStats->cca_busy_time) + pChStats->cca_busy_time -= nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME]); + + } + return WIFI_SUCCESS; +} + +void LLStatsCommand::getClearRspParams(u32 *stats_clear_rsp_mask, u8 *stop_rsp) +{ + *stats_clear_rsp_mask = mClearRspParams.stats_clear_rsp_mask; + *stop_rsp = mClearRspParams.stop_rsp; +} + +wifi_error LLStatsCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +wifi_error LLStatsCommand::notifyResponse() +{ + wifi_error ret = WIFI_SUCCESS; + + /* Indicate stats to framework only if both radio and iface stats + * are present */ + if (mResultsParams.radio_stat && mResultsParams.iface_stat) { + if (mNumRadios > mNumRadiosAllocated) { + ALOGE("%s: Force reset mNumRadios=%d to allocated=%d", + __FUNCTION__, mNumRadios, mNumRadiosAllocated); + mNumRadios = mNumRadiosAllocated; + } + mHandler.on_link_stats_results(mRequestId, + mResultsParams.iface_stat, mNumRadios, + mResultsParams.radio_stat); + } else { + ret = WIFI_ERROR_INVALID_ARGS; + } + + clearStats(); + + return ret; +} + + +void LLStatsCommand::clearStats() +{ + if(mResultsParams.radio_stat) + { + wifi_radio_stat *radioStat = mResultsParams.radio_stat; + if (mNumRadios > mNumRadiosAllocated) { + ALOGE("%s: Force reset mNumRadios=%d to allocated=%d", + __FUNCTION__, mNumRadios, mNumRadiosAllocated); + mNumRadios = mNumRadiosAllocated; + } + for (u8 radio = 0; radio < mNumRadios; radio++) { + if (radioStat->tx_time_per_levels) { + free(radioStat->tx_time_per_levels); + radioStat->tx_time_per_levels = NULL; + } + radioStat = (wifi_radio_stat *)((u8 *)radioStat + + sizeof(wifi_radio_stat) + (sizeof(wifi_channel_stat) * + radioStat->num_channels)); + } + free(mResultsParams.radio_stat); + mResultsParams.radio_stat = NULL; + mRadioStatsSize = 0; + mNumRadios = 0; + mNumRadiosAllocated = 0; + } + if(mResultsParams.iface_stat) + { + free(mResultsParams.iface_stat); + mResultsParams.iface_stat = NULL; + } +} + + +int LLStatsCommand::handleResponse(WifiEvent &reply) +{ + unsigned i=0; + int status = WIFI_ERROR_NONE; + WifiVendorCommand::handleResponse(reply); + + // Parse the vendordata and get the attribute + + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET: + { + u32 resultsBufSize = 0; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1]; + int rem; + wifi_radio_stat *radioStatsBuf; + + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE not found", + __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + + switch(nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE])) + { + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO: + { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mNumRadios = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS]); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS + ]) + { + ALOGE("%s:" + "QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + + resultsBufSize += (nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]) + * sizeof(wifi_channel_stat) + + sizeof(wifi_radio_stat)); + + radioStatsBuf = (wifi_radio_stat *)realloc( + mResultsParams.radio_stat, + mRadioStatsSize + resultsBufSize); + if (!radioStatsBuf) + { + ALOGE("%s: radio_stat: malloc Failed", __FUNCTION__); + status = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + mResultsParams.radio_stat = radioStatsBuf; + + //Move the buffer to populate current radio stats + radioStatsBuf = (wifi_radio_stat *)( + (u8 *)mResultsParams.radio_stat + + mRadioStatsSize); + memset(radioStatsBuf, 0, resultsBufSize); + mRadioStatsSize += resultsBufSize; + mNumRadiosAllocated ++; + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS]) + radioStatsBuf->num_tx_levels = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS]); + + wifi_channel_stat *pWifiChannelStats; + status = get_wifi_radio_stats(radioStatsBuf, + tb_vendor); + if(status != WIFI_SUCCESS) + { + goto cleanup; + } +#ifdef QC_HAL_DEBUG + ALOGV("radio :%u onTime :%u txTime :%u rxTime :%u" + " onTimeScan :%u onTimeNbd :%u onTimeGscan :%u" + " onTimeRoamScan :%u onTimePnoScan :%u" + " onTimeHs20 :%u numChannels :%u num_tx_levels: %u", + radioStatsBuf->radio, + radioStatsBuf->on_time, + radioStatsBuf->tx_time, + radioStatsBuf->rx_time, + radioStatsBuf->on_time_scan, + radioStatsBuf->on_time_nbd, + radioStatsBuf->on_time_gscan, + radioStatsBuf->on_time_roam_scan, + radioStatsBuf->on_time_pno_scan, + radioStatsBuf->on_time_hs20, + radioStatsBuf->num_channels, + radioStatsBuf->num_tx_levels); +#ifdef QC_HAL_DEBUG + for (i = 0; i < radioStatsBuf->num_tx_levels; i++) { + ALOGV("Power level: %u tx_time: %u", i, + radioStatsBuf->tx_time_per_levels[i]); + } +#endif + ALOGV("%5s | %10s | %11s | %11s | %6s | %11s", "width", + "CenterFreq", "CenterFreq0", "CenterFreq1", + "onTime", "ccaBusyTime"); +#endif + for ( i=0; i < radioStatsBuf->num_channels; i++) + { + pWifiChannelStats = + (wifi_channel_stat *) ( + (u8 *)radioStatsBuf->channels + + (i * sizeof(wifi_channel_stat))); + +#ifdef QC_HAL_DEBUG + ALOGV("%5u | %10u | %11u | %11u | %6u | %11u", + pWifiChannelStats->channel.width, + pWifiChannelStats->channel.center_freq, + pWifiChannelStats->channel.center_freq0, + pWifiChannelStats->channel.center_freq1, + pWifiChannelStats->on_time, + pWifiChannelStats->cca_busy_time); +#endif + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE: + { + resultsBufSize = sizeof(wifi_iface_stat); + mResultsParams.iface_stat = + (wifi_iface_stat *) malloc (resultsBufSize); + if (!mResultsParams.iface_stat) + { + ALOGE("%s: iface_stat: malloc Failed", __FUNCTION__); + status = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + memset(mResultsParams.iface_stat, 0, resultsBufSize); + status = get_wifi_interface_info( + &mResultsParams.iface_stat->info, tb_vendor); + if(status != WIFI_SUCCESS) + { + goto cleanup; + } + status = get_wifi_iface_stats(mResultsParams.iface_stat, + tb_vendor); + if(status != WIFI_SUCCESS) + { + goto cleanup; + } + + /* Driver/firmware might send this attribute when there + * are no peers connected. + * So that, the event + * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS can be + * avoided. + */ + if (tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]) + { + mResultsParams.iface_stat->num_peers = + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]); +#ifdef QC_HAL_DEBUG + ALOGV("%s: numPeers is %u\n", __FUNCTION__, + mResultsParams.iface_stat->num_peers); +#endif + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS: + { + struct nlattr *peerInfo; + wifi_iface_stat *pIfaceStat = NULL; + u32 numPeers, num_rates = 0; + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]) + { + ALOGE("%s:QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } +#ifdef QC_HAL_DEBUG + ALOGV(" numPeers is %u in %s\n", + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]), + __FUNCTION__); +#endif + if((numPeers = nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])) > 0) + { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + for (peerInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]); + nla_ok(peerInfo, rem); + peerInfo = nla_next(peerInfo, &(rem))) + { + struct nlattr *tb2[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; + + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, + (struct nlattr *) nla_data(peerInfo), + nla_len(peerInfo), NULL); + + if (!tb2[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]) + { + ALOGE("%s:" + "QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + num_rates += nla_get_u32(tb2[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]); + } + resultsBufSize += (numPeers * sizeof(wifi_peer_info) + + num_rates * sizeof(wifi_rate_stat) + + sizeof (wifi_iface_stat)); + pIfaceStat = (wifi_iface_stat *) malloc ( + resultsBufSize); + if (!pIfaceStat) + { + ALOGE("%s: pIfaceStat: malloc Failed", __FUNCTION__); + status = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + memset(pIfaceStat, 0, resultsBufSize); + if(mResultsParams.iface_stat) { + if(resultsBufSize >= sizeof(wifi_iface_stat)) { + memcpy ( pIfaceStat, mResultsParams.iface_stat, + sizeof(wifi_iface_stat)); + free (mResultsParams.iface_stat); + mResultsParams.iface_stat = pIfaceStat; + } else { + ALOGE("%s: numPeers = %u, num_rates= %u, " + "either numPeers or num_rates is invalid", + __FUNCTION__,numPeers,num_rates); + status = WIFI_ERROR_UNKNOWN; + free(pIfaceStat); + goto cleanup; + } + } + wifi_peer_info *pPeerStats; + pIfaceStat->num_peers = numPeers; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + num_rates = 0; + for (peerInfo = (struct nlattr *) nla_data(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]), + rem = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]); + nla_ok(peerInfo, rem); + peerInfo = nla_next(peerInfo, &(rem))) + { + struct nlattr *tb2[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1]; + pPeerStats = (wifi_peer_info *) ( + (u8 *)pIfaceStat->peer_info + + (i++ * sizeof(wifi_peer_info)) + + (num_rates * sizeof(wifi_rate_stat))); + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, + (struct nlattr *) nla_data(peerInfo), + nla_len(peerInfo), NULL); + status = get_wifi_peer_info(pPeerStats, tb2); + if(status != WIFI_SUCCESS) + { + goto cleanup; + } + num_rates += pPeerStats->num_rate; + } + } + + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_INVALID: + default: + //error case should not happen print log + ALOGE("%s: Wrong LLStats subcmd received %d", __FUNCTION__, + mSubcmd); + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR: + { + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + ALOGI("Resp mask : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK])); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + ALOGI("STOP resp : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP])); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mClearRspParams.stats_clear_rsp_mask = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mClearRspParams.stop_rsp = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]); + break; + } + default : + ALOGE("%s: Wrong LLStats subcmd received %d", __FUNCTION__, mSubcmd); + } + return NL_SKIP; + +cleanup: + clearStats(); + return status; +} + +//Implementation of the functions exposed in linklayer.h +wifi_error wifi_set_link_stats(wifi_interface_handle iface, + wifi_link_layer_params params) +{ + wifi_error ret; + LLStatsCommand *LLCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + hal_info *info = getHalInfo(handle); + + if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) { + ALOGI("%s: LLS is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ALOGI("mpdu_size_threshold : %u, aggressive_statistics_gathering : %u", + params.mpdu_size_threshold, params.aggressive_statistics_gathering); + LLCommand = LLStatsCommand::instance(handle); + if (LLCommand == NULL) { + ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET); + + /* create the message */ + ret = LLCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = LLCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the attributes*/ + nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + /**/ + ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD, + params.mpdu_size_threshold); + if (ret != WIFI_SUCCESS) + goto cleanup; + /**/ + ret = LLCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING, + params.aggressive_statistics_gathering); + if (ret != WIFI_SUCCESS) + goto cleanup; + LLCommand->attr_end(nl_data); + + ret = LLCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + +cleanup: + return ret; +} + +//Implementation of the functions exposed in LLStats.h +wifi_error wifi_get_link_stats(wifi_request_id id, + wifi_interface_handle iface, + wifi_stats_result_handler handler) +{ + wifi_error ret; + LLStatsCommand *LLCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + hal_info *info = getHalInfo(handle); + + if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) { + ALOGI("%s: LLS is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + LLCommand = LLStatsCommand::instance(handle); + if (LLCommand == NULL) { + ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET); + + LLCommand->initGetContext(id); + + LLCommand->setHandler(handler); + + /* create the message */ + ret = LLCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = LLCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + /*add the attributes*/ + nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK, + 7); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /**/ + LLCommand->attr_end(nl_data); + + ret = LLCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + if (ret != WIFI_SUCCESS) { + LLCommand->clearStats(); + goto cleanup; + } + + if (ret == WIFI_SUCCESS) + ret = LLCommand->notifyResponse(); + +cleanup: + return ret; +} + + +//Implementation of the functions exposed in LLStats.h +wifi_error wifi_clear_link_stats(wifi_interface_handle iface, + u32 stats_clear_req_mask, + u32 *stats_clear_rsp_mask, + u8 stop_req, u8 *stop_rsp) +{ + wifi_error ret; + LLStatsCommand *LLCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + hal_info *info = getHalInfo(handle); + + if (!(info->supported_feature_set & WIFI_FEATURE_LINK_LAYER_STATS)) { + ALOGI("%s: LLS is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ALOGI("clear_req : %x, stop_req : %u", stats_clear_req_mask, stop_req); + LLCommand = LLStatsCommand::instance(handle); + if (LLCommand == NULL) { + ALOGE("%s: Error LLStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR); + + /* create the message */ + ret = LLCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = LLCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + /*add the attributes*/ + nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + /**/ + ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK, + stats_clear_req_mask); + if (ret != WIFI_SUCCESS) + goto cleanup; + /**/ + ret = LLCommand->put_u8(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ, + stop_req); + if (ret != WIFI_SUCCESS) + goto cleanup; + LLCommand->attr_end(nl_data); + + ret = LLCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + + LLCommand->getClearRspParams(stats_clear_rsp_mask, stop_rsp); + +cleanup: + delete LLCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/llstatscommand.h b/wcn6740/qcwcn/wifi_hal/llstatscommand.h new file mode 100644 index 0000000..86b9672 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/llstatscommand.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_HAL_LLSTATSCOMMAND_H__ +#define __WIFI_HAL_LLSTATSCOMMAND_H__ + +#include <stdint.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <net/if.h> + +#include "nl80211_copy.h" +#include "common.h" +#include "cpp_bindings.h" +#include "link_layer_stats.h" + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +typedef struct{ + u32 stats_clear_rsp_mask; + u8 stop_rsp; +} LLStatsClearRspParams; + +typedef struct{ + wifi_iface_stat *iface_stat; + int num_radios; + wifi_radio_stat *radio_stat; +} LLStatsResultsParams; + +typedef enum{ + eLLStatsSetParamsInvalid = 0, + eLLStatsClearRspParams, +} eLLStatsRspRarams; + +class LLStatsCommand: public WifiVendorCommand +{ +private: + static LLStatsCommand *mLLStatsCommandInstance; + + LLStatsClearRspParams mClearRspParams; + + LLStatsResultsParams mResultsParams; + + wifi_stats_result_handler mHandler; + + wifi_request_id mRequestId; + + u32 mRadioStatsSize; + + // mNumRadios is decoded from tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS] + // nNumRadiosAllocated is the actual radio stats received. + u8 mNumRadios; + u8 mNumRadiosAllocated; + + LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + +public: + static LLStatsCommand* instance(wifi_handle handle); + + virtual ~LLStatsCommand(); + + // This function implements creation of LLStats specific Request + // based on the request type + virtual wifi_error create(); + + virtual void setSubCmd(u32 subcmd); + + virtual void initGetContext(u32 reqid); + + virtual wifi_error requestResponse(); + + virtual wifi_error notifyResponse(); + + virtual int handleResponse(WifiEvent &reply); + + virtual void getClearRspParams(u32 *stats_clear_rsp_mask, u8 *stop_rsp); + + virtual wifi_error get_wifi_iface_stats(wifi_iface_stat *stats, + struct nlattr **tb_vendor); + + virtual void setHandler(wifi_stats_result_handler handler); + + virtual void clearStats(); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/nan.cpp b/wcn6740/qcwcn/wifi_hal/nan.cpp new file mode 100644 index 0000000..adf73d2 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan.cpp @@ -0,0 +1,2116 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "sync.h" + +#include "wifi_hal.h" +#include "nan_i.h" +#include "common.h" +#include "cpp_bindings.h" +#include <utils/Log.h> +#include <errno.h> +#include "nancommand.h" +#include "vendor_definitions.h" +#include "wificonfigcommand.h" +#include <ctype.h> +#include <openssl/sha.h> +#include <openssl/evp.h> + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + +#define OUT_OF_BAND_SERVICE_INSTANCE_ID 0 + +//Singleton Static Instance +NanCommand* NanCommand::mNanCommandInstance = NULL; + +//Implementation of the functions exposed in nan.h +wifi_error nan_register_handler(wifi_interface_handle iface, + NanCallbackHandler handlers) +{ + // Obtain the singleton instance + wifi_error ret; + NanCommand *nanCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + + nanCommand = NanCommand::instance(wifiHandle); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->setCallbackHandler(handlers); + return ret; +} + +wifi_error nan_get_version(wifi_handle handle, + NanVersion* version) +{ + *version = (NAN_MAJOR_VERSION <<16 | NAN_MINOR_VERSION << 8 | NAN_MICRO_VERSION); + return WIFI_SUCCESS; +} + +/* Function to send enable request to the wifi driver.*/ +wifi_error nan_enable_request(transaction_id id, + wifi_interface_handle iface, + NanEnableRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + NanCommand *t_nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanEnable(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanEnable Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + + if (ret == WIFI_SUCCESS) { + t_nanCommand = NanCommand::instance(wifiHandle); + if (t_nanCommand != NULL) { + t_nanCommand->allocSvcParams(); + } + } + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send disable request to the wifi driver.*/ +wifi_error nan_disable_request(transaction_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + NanCommand *t_nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanDisable(id); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanDisable Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + + if (ret == WIFI_SUCCESS) { + t_nanCommand = NanCommand::instance(wifiHandle); + if (t_nanCommand != NULL) { + t_nanCommand->deallocSvcParams(); + } + } + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send publish request to the wifi driver.*/ +wifi_error nan_publish_request(transaction_id id, + wifi_interface_handle iface, + NanPublishRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanPublish(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanPublish Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send publish cancel to the wifi driver.*/ +wifi_error nan_publish_cancel_request(transaction_id id, + wifi_interface_handle iface, + NanPublishCancelRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanPublishCancel(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanPublishCancel Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send Subscribe request to the wifi driver.*/ +wifi_error nan_subscribe_request(transaction_id id, + wifi_interface_handle iface, + NanSubscribeRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanSubscribe(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanSubscribe Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to cancel subscribe to the wifi driver.*/ +wifi_error nan_subscribe_cancel_request(transaction_id id, + wifi_interface_handle iface, + NanSubscribeCancelRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + NanCommand *t_nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanSubscribeCancel(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanSubscribeCancel Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + + if (ret == WIFI_SUCCESS) { + t_nanCommand = NanCommand::instance(wifiHandle); + if (t_nanCommand != NULL) { + t_nanCommand->deleteServiceId(msg->subscribe_id, + 0, NAN_ROLE_SUBSCRIBER); + } + } + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send NAN follow up request to the wifi driver.*/ +wifi_error nan_transmit_followup_request(transaction_id id, + wifi_interface_handle iface, + NanTransmitFollowupRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanTransmitFollowup(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanTransmitFollowup Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send NAN statistics request to the wifi driver.*/ +wifi_error nan_stats_request(transaction_id id, + wifi_interface_handle iface, + NanStatsRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanStats(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanStats Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send NAN configuration request to the wifi driver.*/ +wifi_error nan_config_request(transaction_id id, + wifi_interface_handle iface, + NanConfigRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanConfig(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanConfig Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send NAN request to the wifi driver.*/ +wifi_error nan_tca_request(transaction_id id, + wifi_interface_handle iface, + NanTCARequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanTCA(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanTCA Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to send NAN Beacon sdf payload to the wifi driver. + This instructs the Discovery Engine to begin publishing the + received payload in any Beacon or Service Discovery Frame + transmitted*/ +wifi_error nan_beacon_sdf_payload_request(transaction_id id, + wifi_interface_handle iface, + NanBeaconSdfPayloadRequest* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanBeaconSdfPayload(id, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanBeaconSdfPayload Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +wifi_error nan_get_sta_parameter(transaction_id id, + wifi_interface_handle iface, + NanStaParameter* msg) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + + nanCommand = NanCommand::instance(wifiHandle); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->getNanStaParameter(iface, msg); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: getNanStaParameter Error:%d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + return ret; +} + +/* Function to get NAN capabilities */ +wifi_error nan_get_capabilities(transaction_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanCapabilities(id); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanCapabilities Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +/* Function to get NAN capabilities */ +wifi_error nan_debug_command_config(transaction_id id, + wifi_interface_handle iface, + NanDebugParams debug, + int debug_msg_length) +{ + wifi_error ret; + NanCommand *nanCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + if (debug_msg_length <= 0) { + ALOGE("%s: Invalid debug message length = %d", __FUNCTION__, + debug_msg_length); + return WIFI_ERROR_UNKNOWN; + } + + nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + if (nanCommand == NULL) { + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nanCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = nanCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = nanCommand->putNanDebugCommand(debug, debug_msg_length); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanDebugCommand Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d",__FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +wifi_error nan_initialize_vendor_cmd(wifi_interface_handle iface, + NanCommand **nanCommand) +{ + wifi_error ret; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + if (nanCommand == NULL) { + ALOGE("%s: Error nanCommand NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + *nanCommand = new NanCommand(wifiHandle, + 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_NDP); + if (*nanCommand == NULL) { + ALOGE("%s: Object creation failed", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = (*nanCommand)->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = (*nanCommand)->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + return WIFI_SUCCESS; + +cleanup: + delete *nanCommand; + return ret; +} + +wifi_error nan_data_interface_create(transaction_id id, + wifi_interface_handle iface, + char* iface_name) +{ + ALOGV("NAN_DP_INTERFACE_CREATE"); + wifi_error ret; + struct nlattr *nlData; + NanCommand *nanCommand = NULL; + WiFiConfigCommand *wifiConfigCommand; + wifi_handle handle = getWifiHandle(iface); + hal_info *info = getHalInfo(handle); + bool ndi_created = false; + + if (iface_name == NULL) { + ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", + __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + if (check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI, + &info->driver_supported_features)) { + wifiConfigCommand = new WiFiConfigCommand(handle, + get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, + info->interfaces[0]->id); + wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, iface_name); + wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, + NL80211_IFTYPE_STATION); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Create intf failed, Error:%d", __FUNCTION__, ret); + delete wifiConfigCommand; + return ret; + } + ndi_created = true; + delete wifiConfigCommand; + } + + ret = nan_initialize_vendor_cmd(iface, &nanCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + goto delete_ndi; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + if (nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE) || + nanCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + id) || + nanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + iface_name)) { + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + nanCommand->attr_end(nlData); + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + +delete_ndi: + if (ndi_created && ret != WIFI_SUCCESS) { + wifiConfigCommand = new WiFiConfigCommand(handle, + get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return ret; + } + wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, + if_nametoindex(iface_name)); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) + ALOGE("%s: Delete intf failed", __FUNCTION__); + + delete wifiConfigCommand; + } + return ret; +} + +wifi_error nan_data_interface_delete(transaction_id id, + wifi_interface_handle iface, + char* iface_name) +{ + ALOGV("NAN_DP_INTERFACE_DELETE"); + wifi_error ret; + struct nlattr *nlData; + NanCommand *nanCommand = NULL; + WiFiConfigCommand *wifiConfigCommand; + wifi_handle handle = getWifiHandle(iface); + hal_info *info = getHalInfo(handle); + + if (iface_name == NULL) { + ALOGE("%s: Invalid Nan Data Interface Name. \n", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", + __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ret = nan_initialize_vendor_cmd(iface, + &nanCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + goto delete_ndi; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + if (nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE) || + nanCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + id) || + nanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + iface_name)) { + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + nanCommand->attr_end(nlData); + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + +delete_ndi: + if ((check_feature(QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI, + &info->driver_supported_features)) && + if_nametoindex(iface_name)) { + wifiConfigCommand = new WiFiConfigCommand(handle, + get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, + if_nametoindex(iface_name)); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + if (wifiConfigCommand->requestEvent() != WIFI_SUCCESS) { + ALOGE("%s: Delete intf failed", __FUNCTION__); + } + delete wifiConfigCommand; + } + + return ret; +} + +/* Service ID using SHA256 */ +static bool +ndp_create_service_id(const u8 *service_name, + u32 service_name_len, u8 *service_id) +{ + u8 out_service_id[NAN_SVC_HASH_SIZE] = {0}; + u8 *mod_service_name; + unsigned char prop_oob_service_name[NAN_DEF_SVC_NAME_LEN + 1] = + "Wi-Fi Aware Data Path"; + unsigned char prop_oob_service_name_lowercase[NAN_DEF_SVC_NAME_LEN + 1] = + "wi-fi aware data path"; + bool is_default = false; + int i; + + if (!service_name) { + ALOGE("%s: NULL service name", __FUNCTION__); + return false; + } + + if (!service_name_len) { + ALOGE("%s: Zero service name length", __FUNCTION__); + return false; + } + + if (!service_id) { + ALOGE("%s: NULL service ID", __FUNCTION__); + return false; + } + + mod_service_name = (u8 *)malloc(service_name_len); + if (!mod_service_name) { + ALOGE("%s: malloc failed", __FUNCTION__); + return false; + } + + memset(mod_service_name, 0, service_name_len); + memcpy(mod_service_name, service_name, service_name_len); + if ((service_name_len == NAN_DEF_SVC_NAME_LEN) && + (!memcmp(mod_service_name, prop_oob_service_name, service_name_len) + || !memcmp(mod_service_name, + prop_oob_service_name_lowercase, service_name_len))) + is_default = true; + + for (i = 0; i < service_name_len; i++) { + /* + * As per NAN spec, the only acceptable singlebyte UTF-8 symbols for a + * Service Name are alphanumeric values (A-Z, a-z, 0-9), the hyphen ('-'), + * the underscore ('_'), and the period ('.'). + * These checks are added for all service names except the above defined + * default service name. + */ + if (!is_default && !isalnum(mod_service_name[i]) && + (mod_service_name[i] != '_') && (mod_service_name[i] != '-') && + (mod_service_name[i] != '.')) { + free(mod_service_name); + return false; + } + + if ((mod_service_name[i] == ' ') && (is_default)) + goto end; + + /* + * The service_name hash SHALL always be done on a lower-case + * version of service_name which was passed down. Therefore, + * before passing the service_name to the SHA256 function first + * run through the string and call tolower on each byte. + */ + mod_service_name[i] = tolower(mod_service_name[i]); + } + +end: + SHA256(mod_service_name, service_name_len, out_service_id); + /* + * As per NAN spec, Service ID is the first 48 bits of the SHA-256 hash + * of the Service Name + */ + memcpy(service_id, out_service_id, NAN_SVC_ID_SIZE); + + free(mod_service_name); + return true; +} + +/* + * PMK = PBKDF2(<pass phrase>, <Salt Version>||<Cipher Suite ID>||<Service ID>|| + * <Publisher NMI>, 4096, 32) + * ndp_passphrase_to_pmk: API to calculate the service ID and PMK. + * @pmk: output value of Hash + * @passphrase: secret key + * @salt_version: 00 + * @csid: cipher suite ID: 01 + * As per NAN spec, below are the values defined for CSID attribute: + * 1 - NCS-SK-128 Cipher Suite + * 2 - NCS-SK-256 Cipher Suite + * 3 - NCS-PK-2WDH-128 Cipher Suite + * 4 - NCS-PK-2WDH-256 Cipher Suite + * Other values are reserved + * @service_id: Hash value of SHA256 on service_name + * @peer_mac: Publisher NAN Management Interface address + * @iterations: 4096 + * @pmk_len: 32 + */ +static int +ndp_passphrase_to_pmk(u32 cipher_type, u8 *pmk, u8 *passphrase, + u32 passphrase_len, u8 *service_name, + u32 service_name_len, u8 *svc_id, u8 *peer_mac) +{ + int result = 0; + u8 pmk_hex[NAN_PMK_INFO_LEN] = {0}; + u8 salt[NAN_SECURITY_SALT_SIZE] = {0}; + u8 service_id[NAN_SVC_ID_SIZE] = {0}; + unsigned char *pos = NULL; + unsigned char salt_version = 0; + u8 csid; + /* We read only first 3-bits, as only 1-4 values are expected currently */ + csid = (u8)(cipher_type & 0x7); + if (csid == 0) + csid = NAN_DEFAULT_NCS_SK; + + if (svc_id != NULL) { + ALOGV("Service ID received from the pool"); + memcpy(service_id, svc_id, NAN_SVC_ID_SIZE); + } else if (ndp_create_service_id((const u8 *)service_name, + service_name_len, service_id) == false) { + ALOGE("Failed to create service ID"); + return result; + } + + pos = salt; + /* salt version */ + *pos++ = salt_version; + /* CSID */ + *pos++ = csid; + /* Service ID */ + memcpy(pos, service_id, NAN_SVC_ID_SIZE); + pos += NAN_SVC_ID_SIZE; + /* Publisher NMI */ + memcpy(pos, peer_mac, NAN_MAC_ADDR_LEN); + pos += NAN_MAC_ADDR_LEN; + + ALOGV("salt dump"); + hexdump(salt, NAN_SECURITY_SALT_SIZE); + + result = PKCS5_PBKDF2_HMAC((const char *)passphrase, passphrase_len, salt, + sizeof(salt), NAN_PMK_ITERATIONS, + (const EVP_MD *) EVP_sha256(), + NAN_PMK_INFO_LEN, pmk_hex); + if (result) + memcpy(pmk, pmk_hex, NAN_PMK_INFO_LEN); + + return result; +} + +wifi_error nan_data_request_initiator(transaction_id id, + wifi_interface_handle iface, + NanDataPathInitiatorRequest* msg) +{ + ALOGV("NAN_DP_REQUEST_INITIATOR"); + wifi_error ret; + struct nlattr *nlData, *nlCfgQos; + NanCommand *nanCommand = NULL; + NanCommand *t_nanCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + + if (msg == NULL) + return WIFI_ERROR_INVALID_ARGS; + + ret = nan_initialize_vendor_cmd(iface, + &nanCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + t_nanCommand = NanCommand::instance(wifiHandle); + if (t_nanCommand == NULL) + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + + if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) && + (msg->key_info.body.pmk_info.pmk_len == 0) && + (msg->key_info.body.passphrase_info.passphrase_len == 0)) { + ALOGE("%s: Failed-Initiator req, missing pmk and passphrase", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) && + (msg->requestor_instance_id == OUT_OF_BAND_SERVICE_INSTANCE_ID) && + (msg->service_name_len == 0)) { + ALOGE("%s: Failed-Initiator req, missing service name for out of band request", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST) || + nanCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + id) || + nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + msg->requestor_instance_id) || + nanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + (char *)msg->peer_disc_mac_addr, + NAN_MAC_ADDR_LEN) || + nanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + msg->ndp_iface)) { + goto cleanup; + } + + if (msg->channel_request_type != NAN_DP_CHANNEL_NOT_REQUESTED) { + if (nanCommand->put_u32 ( + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG, + msg->channel_request_type) || + nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + msg->channel)) + goto cleanup; + } + + if (msg->app_info.ndp_app_info_len != 0) { + if (nanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + (char *)msg->app_info.ndp_app_info, + msg->app_info.ndp_app_info_len)) { + goto cleanup; + } + } + + if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) { + nlCfgQos = + nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS); + if (!nlCfgQos) + goto cleanup; + /* TBD Qos Info */ + nanCommand->attr_end(nlCfgQos); + } + if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) { + if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID, + msg->cipher_type)) + goto cleanup; + } + if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) { + if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + ALOGE("%s: Invalid pmk len:%d", __FUNCTION__, + msg->key_info.body.pmk_info.pmk_len); + goto cleanup; + } + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK, + (char *)msg->key_info.body.pmk_info.pmk, + msg->key_info.body.pmk_info.pmk_len)) + goto cleanup; + } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) { + if (msg->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN || + msg->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__, + msg->key_info.body.passphrase_info.passphrase_len); + goto cleanup; + } + u8 *service_id = NULL; + + if (t_nanCommand != NULL) + service_id = t_nanCommand->getServiceId(msg->requestor_instance_id, + NAN_ROLE_SUBSCRIBER); + if (service_id == NULL) + ALOGE("%s: Entry not found for Instance ID:%d", + __FUNCTION__, msg->requestor_instance_id); + if (((service_id != NULL) || (msg->service_name_len)) && + ndp_passphrase_to_pmk(msg->cipher_type, + msg->key_info.body.pmk_info.pmk, + msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len, + msg->service_name, msg->service_name_len, + service_id, msg->peer_disc_mac_addr)) { + msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN; + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK, + (char *)msg->key_info.body.pmk_info.pmk, + msg->key_info.body.pmk_info.pmk_len)) + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + (char *)msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len)) + goto cleanup; + } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + (char *)msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len)) { + goto cleanup; + } + } + if (msg->service_name_len) { + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, + (char *)msg->service_name, msg->service_name_len)) + goto cleanup; + } + nanCommand->attr_end(nlData); + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +wifi_error nan_data_indication_response(transaction_id id, + wifi_interface_handle iface, + NanDataPathIndicationResponse* msg) +{ + ALOGV("NAN_DP_INDICATION_RESPONSE"); + wifi_error ret; + struct nlattr *nlData, *nlCfgQos; + NanCommand *nanCommand = NULL; + NanCommand *t_nanCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + + if (msg == NULL) + return WIFI_ERROR_INVALID_ARGS; + + ret = nan_initialize_vendor_cmd(iface, + &nanCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + t_nanCommand = NanCommand::instance(wifiHandle); + if (t_nanCommand == NULL) + ALOGE("%s: Error NanCommand NULL", __FUNCTION__); + + if ((msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) && + (msg->key_info.body.pmk_info.pmk_len == 0) && + (msg->key_info.body.passphrase_info.passphrase_len == 0)) { + ALOGE("%s: Failed-Initiator req, missing pmk and passphrase", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST) || + nanCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + id) || + nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + msg->ndp_instance_id) || + nanCommand->put_string( + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + msg->ndp_iface) || + nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + msg->rsp_code)) { + goto cleanup; + } + if (msg->app_info.ndp_app_info_len != 0) { + if (nanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + (char *)msg->app_info.ndp_app_info, + msg->app_info.ndp_app_info_len)) { + goto cleanup; + } + } + if (msg->ndp_cfg.qos_cfg == NAN_DP_CONFIG_QOS) { + nlCfgQos = + nanCommand->attr_start(QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS); + if (!nlCfgQos) + goto cleanup; + + /* TBD Qos Info */ + nanCommand->attr_end(nlCfgQos); + } + if (msg->cipher_type != NAN_CIPHER_SUITE_SHARED_KEY_NONE) { + if (nanCommand->put_u32(QCA_WLAN_VENDOR_ATTR_NDP_CSID, + msg->cipher_type)) + goto cleanup; + } + if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) { + if (msg->key_info.body.pmk_info.pmk_len != NAN_PMK_INFO_LEN) { + ALOGE("%s: Invalid pmk len:%d", __FUNCTION__, + msg->key_info.body.pmk_info.pmk_len); + goto cleanup; + } + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK, + (char *)msg->key_info.body.pmk_info.pmk, + msg->key_info.body.pmk_info.pmk_len)) + goto cleanup; + } else if (msg->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) { + if (msg->key_info.body.passphrase_info.passphrase_len < + NAN_SECURITY_MIN_PASSPHRASE_LEN || + msg->key_info.body.passphrase_info.passphrase_len > + NAN_SECURITY_MAX_PASSPHRASE_LEN) { + ALOGE("%s: Invalid passphrase len:%d", __FUNCTION__, + msg->key_info.body.passphrase_info.passphrase_len); + goto cleanup; + } + u8 *service_id = NULL; + + if (t_nanCommand != NULL) + service_id = t_nanCommand->getServiceId(msg->ndp_instance_id, + NAN_ROLE_PUBLISHER); + if (service_id == NULL) + ALOGE("%s: Entry not found for Instance ID:%d", + __FUNCTION__, msg->ndp_instance_id); + if (((service_id != NULL) || (msg->service_name_len)) && + (t_nanCommand != NULL) && + ndp_passphrase_to_pmk(msg->cipher_type, + msg->key_info.body.pmk_info.pmk, + msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len, + msg->service_name, msg->service_name_len, + service_id, t_nanCommand->getNmi())) { + msg->key_info.body.pmk_info.pmk_len = NAN_PMK_INFO_LEN; + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PMK, + (char *)msg->key_info.body.pmk_info.pmk, + msg->key_info.body.pmk_info.pmk_len)) + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + (char *)msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len)) + goto cleanup; + } else if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + (char *)msg->key_info.body.passphrase_info.passphrase, + msg->key_info.body.passphrase_info.passphrase_len)) { + goto cleanup; + } + } + + if (msg->service_name_len) { + if (nanCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, + (char *)msg->service_name, msg->service_name_len)) + goto cleanup; + } + nanCommand->attr_end(nlData); + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +wifi_error nan_data_end(transaction_id id, + wifi_interface_handle iface, + NanDataPathEndRequest* msg) +{ + wifi_error ret; + ALOGV("NAN_DP_END"); + struct nlattr *nlData; + NanCommand *nanCommand = NULL; + + if (msg == NULL) + return WIFI_ERROR_INVALID_ARGS; + + ret = nan_initialize_vendor_cmd(iface, + &nanCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = nanCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (nanCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST) || + nanCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + id) || + nanCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + (char *)msg->ndp_instance_id, + msg->num_ndp_instances * sizeof(u32))) { + goto cleanup; + } + nanCommand->attr_end(nlData); + + ret = nanCommand->requestEvent(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + +cleanup: + delete nanCommand; + return ret; +} + +// Implementation related to nan class common functions +// Constructor +//Making the constructor private since this class is a singleton +NanCommand::NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mHandler, 0,sizeof(mHandler)); + mNanVendorEvent = NULL; + mNanDataLen = 0; + mStaParam = NULL; + memset(mNmiMac, 0, sizeof(mNmiMac)); + mStorePubParams = NULL; + mStoreSubParams = NULL; + mNanMaxPublishes = 0; + mNanMaxSubscribes = 0; + mNanDiscAddrIndDisabled = false; +} + +NanCommand* NanCommand::instance(wifi_handle handle) +{ + hal_info *info; + + if (handle == NULL) { + ALOGE("Handle is invalid"); + return NULL; + } + info = getHalInfo(handle); + if (info == NULL) { + ALOGE("%s: Error hal_info NULL", __FUNCTION__); + return NULL; + } + + if (mNanCommandInstance == NULL) { + mNanCommandInstance = new NanCommand(handle, 0, + OUI_QCA, + info->support_nan_ext_cmd? + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT : + QCA_NL80211_VENDOR_SUBCMD_NAN); + ALOGV("NanCommand %p created", mNanCommandInstance); + return mNanCommandInstance; + } else { + if (handle != getWifiHandle(mNanCommandInstance->mInfo)) { + /* upper layer must have cleaned up the handle and reinitialized, + so we need to update the same */ + ALOGI("Handle different, update the handle"); + mNanCommandInstance->mInfo = (hal_info *)handle; + } + } + ALOGV("NanCommand %p created already", mNanCommandInstance); + return mNanCommandInstance; +} + +void NanCommand::cleanup() +{ + //free the VendorData + if (mVendorData) { + free(mVendorData); + } + mVendorData = NULL; + //cleanup the mMsg + mMsg.destroy(); +} + +NanCommand::~NanCommand() +{ + ALOGV("NanCommand %p destroyed", this); +} + +int NanCommand::handleResponse(WifiEvent &reply){ + return NL_SKIP; +} + +/* Save NAN Management Interface address */ +void NanCommand::saveNmi(u8 *mac) +{ + memcpy(mNmiMac, mac, NAN_MAC_ADDR_LEN); +} + +/* Get NAN Management Interface address */ +u8 *NanCommand::getNmi() +{ + return mNmiMac; +} + +/* + * Save the service ID along with Subscribe/Publish ID and Instance ID, which + * will be used later for Passphrase to PMK calculation. + * + * service_id - Service ID received from Firmware either in NAN/NDP Indication + * sub_pub_handle - Subscribe/Publish ID received in NAN/NDP Indication + * instance_id - Service/NDP instance ID received in NAN/NDP Indication + * pool - Subscriber/Publisher entry based on NAN/NDP Indication + */ +void NanCommand::saveServiceId(u8 *service_id, u16 sub_pub_handle, + u32 instance_id, NanRole pool) +{ + int i; + + if ((service_id == NULL) || (!sub_pub_handle) || (!instance_id)) { + ALOGE("%s: Null Parameter received, sub_pub_handle=%d instance_id=%d", + __FUNCTION__, sub_pub_handle, instance_id); + return; + } + switch(pool) { + case NAN_ROLE_PUBLISHER: + if ((mStorePubParams == NULL) || !mNanMaxPublishes) + return; + for (i = 0; i < mNanMaxPublishes; i++) { + /* In 1:n case there can be multiple publish entries with same + * publish ID, hence save the new entry if instance ID doesn't match + * with the existing entries in the pool + */ + if ((mStorePubParams[i].subscriber_publisher_id) && + (mStorePubParams[i].instance_id != instance_id)) + continue; + + memset(&mStorePubParams[i], 0, sizeof(mStorePubParams)); + memcpy(mStorePubParams[i].service_id, service_id, NAN_SVC_ID_SIZE); + mStorePubParams[i].subscriber_publisher_id = sub_pub_handle; + mStorePubParams[i].instance_id = instance_id; + ALOGV("Added new entry in Publisher pool at index=%d with " + "Publish ID=%d and Instance ID=%d", i, + mStorePubParams[i].subscriber_publisher_id, + mStorePubParams[i].instance_id); + return; + } + if (i == mNanMaxPublishes) + ALOGV("No empty slot found in publisher pool, entry not saved"); + break; + case NAN_ROLE_SUBSCRIBER: + if ((mStoreSubParams == NULL) || !mNanMaxSubscribes) + return; + for (i = 0; i < mNanMaxSubscribes; i++) { + /* In 1:n case there can be multiple subscribe entries with same + * subscribe ID, hence save new entry if instance ID doesn't match + * with the existing entries in the pool + */ + if ((mStoreSubParams[i].subscriber_publisher_id) && + (mStoreSubParams[i].instance_id != instance_id)) + continue; + + memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams)); + memcpy(mStoreSubParams[i].service_id, service_id, NAN_SVC_ID_SIZE); + mStoreSubParams[i].subscriber_publisher_id = sub_pub_handle; + mStoreSubParams[i].instance_id = instance_id; + ALOGV("Added new entry in Subscriber pool at index=%d with " + "Subscribe ID=%d and Instance ID=%d", i, + mStoreSubParams[i].subscriber_publisher_id, + mStoreSubParams[i].instance_id); + return; + } + if (i == mNanMaxSubscribes) + ALOGV("No empty slot found in subscriber pool, entry not saved"); + break; + default: + ALOGE("Invalid Pool: %d", pool); + break; + } +} + +/* + * Get the Service ID from the pool based on the Service/NDP instance ID that + * will be used for Passphrase to PMK calculation in Initiator/Responder request + * + * instance_id - Service/NDP instance ID received in NAN/NDP Indication + * pool - Subscriber/Publisher role based on the Initiator/Responder + */ +u8 *NanCommand::getServiceId(u32 instance_id, NanRole pool) +{ + int i; + + switch(pool) { + case NAN_ROLE_PUBLISHER: + if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes) + return NULL; + ALOGV("Getting Service ID from publisher pool for instance ID=%d", instance_id); + for (i = 0; i < mNanMaxPublishes; i++) { + if (mStorePubParams[i].instance_id == instance_id) + return mStorePubParams[i].service_id; + } + break; + case NAN_ROLE_SUBSCRIBER: + if ((mStoreSubParams == NULL )|| (!instance_id) || !mNanMaxSubscribes) + return NULL; + ALOGV("Getting Service ID from subscriber pool for instance ID=%d", instance_id); + for (i = 0; i < mNanMaxSubscribes; i++) { + if (mStoreSubParams[i].instance_id == instance_id) + return mStoreSubParams[i].service_id; + } + break; + default: + ALOGE("Invalid Pool: %d", pool); + break; + } + return NULL; +} + +/* + * Delete service ID entry from the pool based on the subscriber/Instance ID + * + * sub_handle - Subscriber ID received from the Subscribe Cancel + * instance_id - NDP Instance ID received from the NDP End Indication + */ +void NanCommand::deleteServiceId(u16 sub_handle, + u32 instance_id, NanRole pool) +{ + int i; + + switch(pool) { + case NAN_ROLE_PUBLISHER: + if ((mStorePubParams == NULL) || (!instance_id) || !mNanMaxPublishes) + return; + for (i = 0; i < mNanMaxPublishes; i++) { + /* Delete all the entries that has the matching Instance ID */ + if (mStorePubParams[i].instance_id == instance_id) { + ALOGV("Deleted entry at index=%d from publisher pool " + "with publish ID=%d and instance ID=%d", i, + mStorePubParams[i].subscriber_publisher_id, + mStorePubParams[i].instance_id); + memset(&mStorePubParams[i], 0, sizeof(mStorePubParams)); + } + } + break; + case NAN_ROLE_SUBSCRIBER: + if ((mStoreSubParams == NULL) || (!sub_handle) || !mNanMaxSubscribes) + return; + for (i = 0; i < mNanMaxSubscribes; i++) { + /* Delete all the entries that has the matching subscribe ID */ + if (mStoreSubParams[i].subscriber_publisher_id == sub_handle) { + ALOGV("Deleted entry at index=%d from subsriber pool " + "with subscribe ID=%d and instance ID=%d", i, + mStoreSubParams[i].subscriber_publisher_id, + mStoreSubParams[i].instance_id); + memset(&mStoreSubParams[i], 0, sizeof(mStoreSubParams)); + } + } + break; + default: + ALOGE("Invalid Pool: %d", pool); + break; + } +} + +/* + * Allocate the memory for the Subscribe and Publish pools using the Max values + * mStorePubParams - Points the Publish pool + * mStoreSubParams - Points the Subscribe pool + */ +void NanCommand::allocSvcParams() +{ + if (mNanMaxPublishes < NAN_DEF_PUB_SUB) + mNanMaxPublishes = NAN_DEF_PUB_SUB; + if (mNanMaxSubscribes < NAN_DEF_PUB_SUB) + mNanMaxSubscribes = NAN_DEF_PUB_SUB; + + if ((mStorePubParams == NULL) && mNanMaxPublishes) { + mStorePubParams = + (NanStoreSvcParams *)malloc(mNanMaxPublishes*sizeof(NanStoreSvcParams)); + if (mStorePubParams == NULL) { + ALOGE("%s: Publish pool malloc failed", __FUNCTION__); + deallocSvcParams(); + return; + } + ALOGV("%s: Allocated the Publish pool for max %d entries", + __FUNCTION__, mNanMaxPublishes); + } + if ((mStoreSubParams == NULL) && mNanMaxSubscribes) { + mStoreSubParams = + (NanStoreSvcParams *)malloc(mNanMaxSubscribes*sizeof(NanStoreSvcParams)); + if (mStoreSubParams == NULL) { + ALOGE("%s: Subscribe pool malloc failed", __FUNCTION__); + deallocSvcParams(); + return; + } + ALOGV("%s: Allocated the Subscribe pool for max %d entries", + __FUNCTION__, mNanMaxSubscribes); + } +} + +/* + * Reallocate the memory for Subscribe and Publish pools using the Max values + * mStorePubParams - Points the Publish pool + * mStoreSubParams - Points the Subscribe pool + */ +void NanCommand::reallocSvcParams(NanRole pool) +{ + switch(pool) { + case NAN_ROLE_PUBLISHER: + if ((mStorePubParams != NULL) && mNanMaxPublishes) { + mStorePubParams = + (NanStoreSvcParams *)realloc(mStorePubParams, + mNanMaxPublishes*sizeof(NanStoreSvcParams)); + if (mStorePubParams == NULL) { + ALOGE("%s: Publish pool realloc failed", __FUNCTION__); + deallocSvcParams(); + return; + } + ALOGV("%s: Reallocated the Publish pool for max %d entries", + __FUNCTION__, mNanMaxPublishes); + } + break; + case NAN_ROLE_SUBSCRIBER: + if ((mStoreSubParams != NULL) && mNanMaxSubscribes) { + mStoreSubParams = + (NanStoreSvcParams *)realloc(mStoreSubParams, + mNanMaxSubscribes*sizeof(NanStoreSvcParams)); + if (mStoreSubParams == NULL) { + ALOGE("%s: Subscribe pool realloc failed", __FUNCTION__); + deallocSvcParams(); + return; + } + ALOGV("%s: Reallocated the Subscribe pool for max %d entries", + __FUNCTION__, mNanMaxSubscribes); + } + break; + default: + ALOGE("Invalid Pool: %d", pool); + break; + } +} + +/* + * Deallocate the Subscribe and Publish pools + * mStorePubParams - Points the Publish pool + * mStoreSubParams - Points the Subscribe pool + */ +void NanCommand::deallocSvcParams() +{ + if (mStorePubParams != NULL) { + free(mStorePubParams); + mStorePubParams = NULL; + ALOGV("%s: Deallocated Publish pool", __FUNCTION__); + } + if (mStoreSubParams != NULL) { + free(mStoreSubParams); + mStoreSubParams = NULL; + ALOGV("%s: Deallocated Subscribe pool", __FUNCTION__); + } +} + +wifi_error NanCommand::setCallbackHandler(NanCallbackHandler nHandler) +{ + wifi_error res; + mHandler = nHandler; + res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NAN); + if (res != WIFI_SUCCESS) { + //error case should not happen print log + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x" + "subcmd=QCA_NL80211_VENDOR_SUBCMD_NAN", __FUNCTION__, mVendor_id); + return res; + } + + res = registerVendorHandler(mVendor_id, QCA_NL80211_VENDOR_SUBCMD_NDP); + if (res != WIFI_SUCCESS) { + //error case should not happen print log + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x" + "subcmd=QCA_NL80211_VENDOR_SUBCMD_NDP", __FUNCTION__, mVendor_id); + return res; + } + return res; +} + +/* This function implements creation of Vendor command */ +wifi_error NanCommand::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + goto out; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + goto out; + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + +out: + if (ret != WIFI_SUCCESS) + mMsg.destroy(); + return ret; +} + +// This function will be the main handler for incoming event +// QCA_NL80211_VENDOR_SUBCMD_NAN +//Call the appropriate callback handler after parsing the vendor data. +int NanCommand::handleEvent(WifiEvent &event) +{ + WifiVendorCommand::handleEvent(event); + ALOGV("%s: Subcmd=%u Vendor data len received:%d", + __FUNCTION__, mSubcmd, mDataLen); + hexdump(mVendorData, mDataLen); + + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN){ + // Parse the vendordata and get the NAN attribute + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + // Populating the mNanVendorEvent and mNanDataLen to point to NAN data. + mNanVendorEvent = (char *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]); + mNanDataLen = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NAN]); + + if (isNanResponse()) { + //handleNanResponse will parse the data and call + //the response callback handler with the populated + //NanResponseMsg + handleNanResponse(); + } else { + //handleNanIndication will parse the data and call + //the corresponding Indication callback handler + //with the corresponding populated Indication event + handleNanIndication(); + } + } else if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NDP) { + // Parse the vendordata and get the NAN attribute + u32 ndpCmdType; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) { + ndpCmdType = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]); + ALOGD("%s: NDP Cmd Type : val 0x%x", + __FUNCTION__, ndpCmdType); + switch (ndpCmdType) { + case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: + handleNdpResponse(NAN_DP_INTERFACE_CREATE, tb_vendor); + break; + case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE: + handleNdpResponse(NAN_DP_INTERFACE_DELETE, tb_vendor); + break; + case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE: + handleNdpResponse(NAN_DP_INITIATOR_RESPONSE, tb_vendor); + break; + case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE: + handleNdpResponse(NAN_DP_RESPONDER_RESPONSE, tb_vendor); + break; + case QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE: + handleNdpResponse(NAN_DP_END, tb_vendor); + break; + case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND: + case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND: + case QCA_WLAN_VENDOR_ATTR_NDP_END_IND: + case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND: + handleNdpIndication(ndpCmdType, tb_vendor); + break; + default: + ALOGE("%s: Invalid NDP subcmd response received %d", + __FUNCTION__, ndpCmdType); + } + } + } else { + //error case should not happen print log + ALOGE("%s: Wrong NAN subcmd received %d", __FUNCTION__, mSubcmd); + } + mNanVendorEvent = NULL; + return NL_SKIP; +} + +/*Helper function to Write and Read TLV called in indication as well as request */ +u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv) +{ + u16 writeLen = 0; + u16 i; + + if (!pInTlv) + { + ALOGE("NULL pInTlv"); + return writeLen; + } + + if (!pOutTlv) + { + ALOGE("NULL pOutTlv"); + return writeLen; + } + + *pOutTlv++ = pInTlv->type & 0xFF; + *pOutTlv++ = (pInTlv->type & 0xFF00) >> 8; + writeLen += 2; + + ALOGV("WRITE TLV type %u, writeLen %u", pInTlv->type, writeLen); + + *pOutTlv++ = pInTlv->length & 0xFF; + *pOutTlv++ = (pInTlv->length & 0xFF00) >> 8; + writeLen += 2; + + ALOGV("WRITE TLV length %u, writeLen %u", pInTlv->length, writeLen); + + for (i=0; i < pInTlv->length; ++i) + { + *pOutTlv++ = pInTlv->value[i]; + } + + writeLen += pInTlv->length; + ALOGV("WRITE TLV value, writeLen %u", writeLen); + return writeLen; +} + +u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize) +{ + u16 readLen = 0; + + if (!pInTlv) + { + ALOGE("NULL pInTlv"); + return readLen; + } + + if (!pOutTlv) + { + ALOGE("NULL pOutTlv"); + return readLen; + } + + if(inBufferSize < NAN_TLV_HEADER_SIZE) { + ALOGE("Insufficient length to process TLV header, inBufferSize = %d", + inBufferSize); + return readLen; + } + + pOutTlv->type = *pInTlv++; + pOutTlv->type |= *pInTlv++ << 8; + readLen += 2; + + ALOGV("READ TLV type %u, readLen %u", pOutTlv->type, readLen); + + pOutTlv->length = *pInTlv++; + pOutTlv->length |= *pInTlv++ << 8; + readLen += 2; + + if(pOutTlv->length > (u16)(inBufferSize - NAN_TLV_HEADER_SIZE)) { + ALOGE("Insufficient length to process TLV header, inBufferSize = %d", + inBufferSize); + return readLen; + } + + ALOGV("READ TLV length %u, readLen %u", pOutTlv->length, readLen); + + if (pOutTlv->length) { + pOutTlv->value = pInTlv; + readLen += pOutTlv->length; + } else { + pOutTlv->value = NULL; + } + + ALOGV("READ TLV readLen %u", readLen); + return readLen; +} + +u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv) +{ + NanTlv nanTlv; + u16 len; + + nanTlv.type = type; + nanTlv.length = length; + nanTlv.value = (u8*)value; + + len = NANTLV_WriteTlv(&nanTlv, pOutTlv); + return (pOutTlv + len); +} diff --git a/wcn6740/qcwcn/wifi_hal/nan_cert.h b/wcn6740/qcwcn/wifi_hal/nan_cert.h new file mode 100644 index 0000000..19b2882 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan_cert.h @@ -0,0 +1,243 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __NAN_CERT_H__ +#define __NAN_CERT_H__ + + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#define NAN_CERT_VERSION 5 +#define NAN_MAX_DEBUG_MESSAGE_DATA_LEN 100 +#define NAN_MAX_ALLOWED_DW_AWAKE_INTERVAL 16 + +typedef struct { + /* NAN master rank being advertised by DE */ + u64 master_rank; + /* NAN master preference being advertised by DE */ + u8 master_pref; + /* random value being advertised by DE */ + u8 random_factor; + /* hop_count from anchor master */ + u8 hop_count; + u32 beacon_transmit_time; + /* NDP channel Frequency */ + u32 ndp_channel_freq; +} NanStaParameter; + +/* NAN Data Path Supported Band */ +typedef enum { + NAN_DATA_PATH_SUPPORTED_BAND_2G = 1, + NAN_DATA_PATH_SUPPORTED_BAND_5G = 2, + NAN_DATA_PATH_SUPPORT_DUAL_BAND = 3 +} NdpSupportedBand; + +/* NAN Responder mode policy */ +typedef enum { + NAN_DATA_RESPONDER_MODE_AUTO = 0, + NAN_DATA_RESPONDER_MODE_ACCEPT = 1, + NAN_DATA_RESPONDER_MODE_REJECT = 2, + NAN_DATA_RESPONDER_MODE_COUNTER = 3, + NAN_DATA_RESPONDER_MODE_COUNTER_NO_CHANNEL_CHANGE = 4 +} NanDataResponderMode; + +/* NAN Data Path M4 response type */ +typedef enum { + NAN_DATA_PATH_M4_RESPONSE_ACCEPT = 1, + NAN_DATA_PATH_M4_RESPONSE_REJECT = 2, + NAN_DATA_PATH_M4_RESPONSE_BADMIC = 3 +} NdpM4ResponseType; + +/* NAN NMF Security Clear type */ +typedef enum { + NAN_NMF_CLEAR_DISABLE = 0, + NAN_NMF_CLEAR_ENABLE = 1 +} NanNmfClearConfig; + +/* NAN Schedule type */ +typedef enum { + NAN_SCHED_VALID = 0, + NAN_SCHED_INVALID_BAD_FA = 1, + NAN_SCHED_INVALID_BAD_NDC = 2, + NAN_SCHED_INVALID_BAD_IMMU = 3 +} NanSchedType; + +/* NAN device type */ +typedef enum { + NAN_DEVICE_TYPE_TEST_BED = 1, + NAN_DEVICE_TYPE_DUT = 2 +} NanDeviceType; + +/* NAN NDPE absent or present */ +typedef enum { + NAN_NDPE_ATTR_PRESENT = 0, + NAN_NDPE_ATTR_ABSENT = 1 +} NanNdpeAttrType; + +/* NAN NDP absent or present */ +typedef enum { + NAN_NDP_ATTR_ABSENT = 0, + NAN_NDP_ATTR_PRESENT = 1 +} NanNdpAttrType; + +/* NAN IPV6 implicit or explicit */ +typedef enum { + NAN_IPV6_EXPLICIT = 0, + NAN_IPV6_IMPLICIT = 1 +} NanIPv6Type; + +/* NAN IPV6 address, port number and protocol type */ +#define NAN_MSG_IPV6_INTF_ADDR_LEN 16 + +typedef struct PACKED +{ + /* Presence of ipv6_intf_addr */ + u32 ipv6_addr_present; + /* Presence of transport Port */ + u32 trans_port_present; + /* Presence of transport Protocol */ + u32 trans_proto_present; + /* ipv6 Interface address */ + u8 ipv6_intf_addr[NAN_MSG_IPV6_INTF_ADDR_LEN]; + /* Transport Port */ + u32 transport_port; + /* Transport Protocol */ + u32 transport_protocol; +} NdpIpTransParams, *pNdpIpTransParams; + + /* + * Definitions of debug subcommand type for the + * generic debug command. + */ +typedef enum { + NAN_TEST_MODE_CMD_NAN_AVAILABILITY = 1, + NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE = 2, + NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL = 3, + NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS = 4, + NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE = 5, + NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE = 6, + NAN_TEST_MODE_CMD_NAN_SCHED_TYPE = 7, + NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG = 8, + NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY = 9, + NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE = 10, + NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY = 11, + NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER = 12, + NAN_TEST_MODE_CMD_CONFIG_QOS = 13, + NAN_TEST_MODE_CMD_DEVICE_TYPE = 14, + NAN_TEST_MODE_CMD_DISABLE_NDPE = 15, + NAN_TEST_MODE_CMD_ENABLE_NDP = 16, + NAN_TEST_MODE_CMD_DISABLE_IPV6_LINK_LOCAL = 17, + NAN_TEST_MODE_CMD_TRANSPORT_IP_PARAM = 18, +} NanDebugModeCmd; + +/* + * This debug command carries any one command type + * followed by corresponding command data content + * as indicated below. + * + * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY + * content: NAN Avaiability attribute blob + * + * command: NAN_TEST_MODE_CMD_NDP_INCLUDE_IMMUTABLE + * content: u32 value (0 - Ignore 1 - Include immuatable, + * 2 - Don't include immutable) + * + * command: NAN_TEST_MODE_CMD_NDP_AVOID_CHANNEL + * content: u32 channel_frequency; (0 - Ignore) + * + * command: NAN_TEST_MODE_CMD_NAN_SUPPORTED_BANDS + * content: u32 supported_bands; (0 . Ignore, 1 . 2g, + * 2 . 5g, 3 . 2g & 5g) + * + * command: NAN_TEST_MODE_CMD_AUTO_RESPONDER_MODE + * content: u32 auto_resp_mode; (0 . Auto, 1 . Accept, + * 2 . Reject, 3 . Counter) + * + * command: NAN_TEST_MODE_CMD_M4_RESPONSE_TYPE + * content: u32 m4_response_type; (0.Ignore, 1.Accept, + * 2.Reject, 3.BadMic) + * + * command: NAN_TEST_MODE_CMD_NAN_SCHED_TYPE + * content: u32 invalid_nan_schedule; (0. Valid sched, + * 1.Invalid Sched bad FA, + * 2.Invalid schedbad NDC, + * 3.Invalid sched bad Immutable) + * + * command: NAN_TEST_MODE_CMD_NAN_NMF_CLEAR_CONFIG + * content: u32 nmf_security_config_val;(0:NAN_NMF_CLEAR_DISABLE, + * 1:NAN_NMF_CLEAR_ENABLE) + * + * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_ULW_NOTIFY + * content: u32 channel_availability;(0/1) + * + * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NEGOTIATE + * content: responder_nmi_mac (Responder NMI Mac Address) + * + * command: NAN_TEST_MODE_CMD_NAN_SCHED_UPDATE_NDL_NOTIFY + * content: NONE + * + * command: NAN_TEST_MODE_CMD_NAN_AVAILABILITY_MAP_ORDER + * content: u32 map_order_val; (0/1) + * + */ +typedef struct PACKED { + /* + * To indicate the debug command type. + */ + u32 cmd; + /* + * To hold the data for the above command + * type. + */ + u8 debug_cmd_data[NAN_MAX_DEBUG_MESSAGE_DATA_LEN]; +} NanDebugParams; + +/* + Function to get the sta_parameter expected by Sigma + as per CAPI spec. +*/ +wifi_error nan_get_sta_parameter(transaction_id id, + wifi_interface_handle iface, + NanStaParameter* msg); + +wifi_error nan_debug_command_config(transaction_id id, + wifi_interface_handle iface, + NanDebugParams msg, + int debug_msg_length); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __NAN_CERT_H__ */ + diff --git a/wcn6740/qcwcn/wifi_hal/nan_i.h b/wcn6740/qcwcn/wifi_hal/nan_i.h new file mode 100644 index 0000000..ad69e18 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan_i.h @@ -0,0 +1,1328 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#ifndef __NAN_I_H__ +#define __NAN_I_H__ + +#include "common.h" +#include "cpp_bindings.h" +#include "wifi_hal.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +#define BIT_NONE 0x00 +#define BIT_0 0x01 +#define BIT_1 0x02 +#define BIT_2 0x04 +#define BIT_3 0x08 +#define BIT_4 0x10 +#define BIT_5 0x20 +#define BIT_6 0x40 +#define BIT_7 0x80 +#define BIT_8 0x0100 +#define BIT_9 0x0200 +#define BIT_10 0x0400 +#define BIT_11 0x0800 +#define BIT_12 0x1000 +#define BIT_13 0x2000 +#define BIT_14 0x4000 +#define BIT_15 0x8000 +#define BIT_16 0x010000 +#define BIT_17 0x020000 +#define BIT_18 0x040000 +#define BIT_19 0x080000 +#define BIT_20 0x100000 +#define BIT_21 0x200000 +#define BIT_22 0x400000 +#define BIT_23 0x800000 +#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 + +/** macro to convert FW MAC address from WMI word format to User Space MAC char array */ +#define FW_MAC_ADDR_TO_CHAR_ARRAY(fw_mac_addr, mac_addr) do { \ + (mac_addr)[0] = ((fw_mac_addr).mac_addr31to0) & 0xff; \ + (mac_addr)[1] = (((fw_mac_addr).mac_addr31to0) >> 8) & 0xff; \ + (mac_addr)[2] = (((fw_mac_addr).mac_addr31to0) >> 16) & 0xff; \ + (mac_addr)[3] = (((fw_mac_addr).mac_addr31to0) >> 24) & 0xff; \ + (mac_addr)[4] = ((fw_mac_addr).mac_addr47to32) & 0xff; \ + (mac_addr)[5] = (((fw_mac_addr).mac_addr47to32) >> 8) & 0xff; \ +} while (0) + +/** macro to convert User space MAC address from char array to FW WMI word format */ +#define CHAR_ARRAY_TO_MAC_ADDR(mac_addr, fw_mac_addr) do { \ + (fw_mac_addr).mac_addr31to0 = \ + ((mac_addr)[0] | ((mac_addr)[1] << 8) \ + | ((mac_addr)[2] << 16) | ((mac_addr)[3] << 24)); \ + (fw_mac_addr).mac_addr47to32 = \ + ((mac_addr)[4] | ((mac_addr)[5] << 8)); \ +} while (0) + +/*--------------------------------------------------------------------------- +* WLAN NAN CONSTANTS +*--------------------------------------------------------------------------*/ + +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_MATCH_IND = 13, + NAN_MSG_ID_MATCH_EXPIRED_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_BEACON_SDF_REQ = 30, + NAN_MSG_ID_BEACON_SDF_RSP = 31, + NAN_MSG_ID_BEACON_SDF_IND = 32, + NAN_MSG_ID_CAPABILITIES_REQ = 33, + NAN_MSG_ID_CAPABILITIES_RSP = 34, + NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND = 35, + NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND = 36, + NAN_MSG_ID_RANGING_RESULT_IND = 37, + NAN_MSG_ID_TESTMODE_REQ = 1025, + NAN_MSG_ID_TESTMODE_RSP = 1026 +} NanMsgId; + +/* + Various TLV Type ID sent as part of NAN Stats Response + or NAN TCA Indication +*/ +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 =5, + NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT = 6, + NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE = 7, + NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE = 8, + NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE = 9, + NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE = 10, + NAN_TLV_TYPE_NAN_DATA_PATH_PARAMS = 11, + NAN_TLV_TYPE_NAN_DATA_SUPPORTED_BAND = 12, + NAN_TLV_TYPE_2G_COMMITTED_DW = 13, + NAN_TLV_TYPE_5G_COMMITTED_DW = 14, + NAN_TLV_TYPE_NAN_DATA_RESPONDER_MODE = 15, + NAN_TLV_TYPE_NAN_DATA_ENABLED_IN_MATCH = 16, + NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY = 17, + NAN_TLV_TYPE_NAN_CSID = 18, + NAN_TLV_TYPE_NAN_SCID = 19, + NAN_TLV_TYPE_NAN_PMK = 20, + NAN_TLV_TYPE_SDEA_CTRL_PARAMS = 21, + NAN_TLV_TYPE_NAN_RANGING_CFG = 22, + NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS = 23, + NAN_TLV_TYPE_NAN20_RANGING_REQUEST = 24, + NAN_TLV_TYPE_NAN20_RANGING_RESULT = 25, + NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED = 26, + NAN_TLV_TYPE_NAN_PASSPHRASE = 27, + NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO = 28, + NAN_TLV_TYPE_DEV_CAP_ATTR_CAPABILITY = 29, + NAN_TLV_TYPE_IP_TRANSPORT_PARAM = 30, + NAN_TLV_TYPE_SERVICE_ID = 31, + 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 = 4100, + 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 = 4110, + 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 = 4120, + NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, + NAN_TLV_TYPE_HOP_COUNT_FORCE, + NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + NAN_TLV_TYPE_RANDOM_UPDATE_TIME = 4124, + NAN_TLV_TYPE_EARLY_WAKEUP, + NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, + NAN_TLV_TYPE_DW_INTERVAL = 4128, + NAN_TLV_TYPE_DB_INTERVAL, + NAN_TLV_TYPE_FURTHER_AVAILABILITY, + NAN_TLV_TYPE_24G_CHANNEL, + NAN_TLV_TYPE_5G_CHANNEL, + NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, + NAN_TLV_TYPE_RANGING_AUTO_RESPONSE_CFG = 4134, + NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON = 4135, + NAN_TLV_TYPE_DW_EARLY_TERMINATION = 4136, + NAN_TLV_TYPE_TX_RX_CHAINS = 4137, + NAN_TLV_TYPE_ENABLE_DEVICE_RANGING = 4138, + 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_WLAN_INFRA_SSID, + NAN_TLV_TYPE_ATTRS_LAST = 12287, + + /* Events Type */ + 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_FAW_MEM_AVAIL, + NAN_TLV_TYPE_EVENTS_LAST = 16383, + + /* TCA 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 = 32767, + + /* 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 = 36863, + + /* Testmode types */ + NAN_TLV_TYPE_TESTMODE_FIRST = 36864, + NAN_TLV_TYPE_TESTMODE_GENERIC_CMD = NAN_TLV_TYPE_TESTMODE_FIRST, + NAN_TLV_TYPE_TESTMODE_LAST = 37000, + + NAN_TLV_TYPE_LAST = 65535 +} NanTlvType; + +/* 8-byte control message header used by NAN*/ +typedef struct PACKED +{ + u16 msgVersion:4; + u16 msgId:12; + u16 msgLen; + u16 handle; + u16 transactionId; +} NanMsgHeader, *pNanMsgHeader; + +/* Enumeration for Version */ +typedef enum +{ + NAN_MSG_VERSION1 = 1, +}NanMsgVersion; + +typedef struct PACKED +{ + u16 type; + u16 length; + u8* value; +} NanTlv, *pNanTlv; + +#define SIZEOF_TLV_HDR (sizeof(NanTlv::type) + sizeof(NanTlv::length)) +/* NAN TLV Groups and Types */ +typedef enum +{ + NAN_TLV_GROUP_FIRST = 0, + NAN_TLV_GROUP_SDF = NAN_TLV_GROUP_FIRST, + NAN_TLV_GROUP_CONFIG, + NAN_TLV_GROUP_STATS, + NAN_TLV_GROUP_ATTRS, + NAN_TLV_NUM_GROUPS, + NAN_TLV_GROUP_LAST = NAN_TLV_NUM_GROUPS +} NanTlvGroup; + +/* NAN Miscellaneous Constants */ +#define NAN_TTL_INFINITE 0 +#define NAN_REPLY_COUNT_INFINITE 0 + +/* 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_BEACONS 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 + +#define NAN_TLV_HEADER_SIZE 4 + +/* NAN Error Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + u16 status; + u16 value; +} NanErrorRspMsg, *pNanErrorRspMsg; + +//* NAN Publish Service Req */ +typedef struct PACKED +{ + u16 ttl; + u16 period; + u32 replyIndFlag:1; + u32 publishType:2; + u32 txType:1; + u32 rssiThresholdFlag:1; + u32 ota_flag:1; + u32 matchAlg:2; + u32 count:8; + u32 connmap:8; + u32 pubTerminatedIndDisableFlag:1; + u32 pubMatchExpiredIndDisableFlag:1; + u32 followupRxIndDisableFlag:1; + u32 reserved2:5; + /* + * Excludes TLVs + * + * Required: Service Name, + * Optional: Tx Match Filter, Rx Match Filter, Service Specific Info, + */ +} NanPublishServiceReqParams, *pNanPublishServiceReqParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanPublishServiceReqParams publishServiceReqParams; + u8 ptlv[]; +} NanPublishServiceReqMsg, *pNanPublishServiceReqMsg; + +/* NAN Publish Service Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanPublishServiceRspMsg, *pNanPublishServiceRspMsg; + +/* NAN Publish Service Cancel Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; +} NanPublishServiceCancelReqMsg, *pNanPublishServiceCancelReqMsg; + +/* NAN Publish Service Cancel Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanPublishServiceCancelRspMsg, *pNanPublishServiceCancelRspMsg; + +/* NAN Publish Terminated Ind */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* reason for the termination */ + u16 reason; + u16 reserved; +} NanPublishTerminatedIndMsg, *pNanPublishTerminatedIndMsg; + +/* Params for NAN Publish Replied Ind */ +typedef struct PACKED +{ + u32 matchHandle; +} NanPublishRepliedIndParams; + +/* NAN Publish Replied Ind */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanPublishRepliedIndParams publishRepliedIndParams; + /* + * Excludes TLVs + * + * Required: MAC Address + * Optional: Received RSSI Value + * + */ + u8 ptlv[]; +} NanPublishRepliedIndMsg, *pNanPublishRepliedIndMsg; + +/* NAN Device Capability Attribute */ +typedef struct PACKED +{ + u32 dfs_master:1; + u32 ext_key_id:1; + u32 simu_ndp_data_recept:1; + u32 ndpe_attr_supp:1; + u32 reserved:28; +} NanDevCapAttrCap, *pNanDevCapAttrCap; + +/* NAN Subscribe Service Req */ +typedef struct PACKED +{ + u16 ttl; + u16 period; + u32 subscribeType:1; + u32 srfAttr:1; + u32 srfInclude:1; + u32 srfSend:1; + u32 ssiRequired:1; + u32 matchAlg:2; + u32 xbit:1; + u32 count:8; + u32 rssiThresholdFlag:1; + u32 ota_flag:1; + u32 subTerminatedIndDisableFlag:1; + u32 subMatchExpiredIndDisableFlag:1; + u32 followupRxIndDisableFlag:1; + u32 reserved:3; + u32 connmap:8; + /* + * Excludes TLVs + * + * Required: Service Name + * Optional: Rx Match Filter, Tx Match Filter, Service Specific Info, + */ +} NanSubscribeServiceReqParams, *pNanSubscribeServiceReqParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanSubscribeServiceReqParams subscribeServiceReqParams; + u8 ptlv[]; +} NanSubscribeServiceReqMsg, *pNanSubscribeServiceReqMsg; + +/* NAN Subscribe Service Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanSubscribeServiceRspMsg, *pNanSubscribeServiceRspMsg; + +/* NAN Subscribe Service Cancel Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; +} NanSubscribeServiceCancelReqMsg, *pNanSubscribeServiceCancelReqMsg; + +/* NAN Subscribe Service Cancel Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanSubscribeServiceCancelRspMsg, *pNanSubscribeServiceCancelRspMsg; + +/* NAN Subscribe Match Ind */ +typedef struct PACKED +{ + u32 matchHandle; + u32 matchOccuredFlag:1; + u32 outOfResourceFlag:1; + u32 reserved:30; +} NanMatchIndParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanMatchIndParams matchIndParams; + u8 ptlv[]; +} NanMatchIndMsg, *pNanMatchIndMsg; + +/* NAN Subscribe Unmatch Ind */ +typedef struct PACKED +{ + u32 matchHandle; +} NanmatchExpiredIndParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanmatchExpiredIndParams matchExpiredIndParams; +} NanMatchExpiredIndMsg, *pNanMatchExpiredIndMsg; + +/* NAN Subscribe Terminated Ind */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* reason for the termination */ + u16 reason; + u16 reserved; +} NanSubscribeTerminatedIndMsg, *pNanSubscribeTerminatedIndMsg; + +/* Event Ind */ +typedef struct PACKED +{ + u32 eventId:8; + u32 reserved:24; +} NanEventIndParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + u8 ptlv[]; +} NanEventIndMsg, *pNanEventIndMsg; + +/* NAN Transmit Followup Req */ +typedef struct PACKED +{ + u32 matchHandle; + u32 priority:4; + u32 window:1; + u32 followupTxRspDisableFlag:1; + u32 reserved:26; + /* + * Excludes TLVs + * + * Required: Service Specific Info or Extended Service Specific Info + */ +} NanTransmitFollowupReqParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanTransmitFollowupReqParams transmitFollowupReqParams; + u8 ptlv[]; +} NanTransmitFollowupReqMsg, *pNanTransmitFollowupReqMsg; + +/* NAN Transmit Followup Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanTransmitFollowupRspMsg, *pNanTransmitFollowupRspMsg; + +/* NAN Publish Followup Ind */ +typedef struct PACKED +{ + u32 matchHandle; + u32 window:1; + u32 reserved:31; + /* + * Excludes TLVs + * + * Required: Service Specific Info or Extended Service Specific Info + */ +} NanFollowupIndParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanFollowupIndParams followupIndParams; + u8 ptlv[]; +} NanFollowupIndMsg, *pNanFollowupIndMsg; + +/* NAN Statistics Req */ +typedef struct PACKED +{ + u32 statsType:8; + u32 clear:1; + u32 reserved:23; +} NanStatsReqParams, *pNanStatsReqParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanStatsReqParams statsReqParams; +} NanStatsReqMsg, *pNanStatsReqMsg; + +/* NAN Statistics Rsp */ +typedef struct PACKED +{ + /* status of the request */ + u16 status; + u16 value; + u8 statsType; + u8 reserved; +} NanStatsRspParams, *pNanStatsRspParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + NanStatsRspParams statsRspParams; + u8 ptlv[]; +} NanStatsRspMsg, *pNanStatsRspMsg; + +typedef struct PACKED +{ + u8 count:7; + u8 s:1; +} NanSidAttr, *pSidAttr; + + +/* NAN Configuration Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + * TLVs: + * + * Required: None. + * Optional: SID, Random Time, Master Preference, WLAN Intra Attr, + * P2P Operation Attr, WLAN IBSS Attr, WLAN Mesh Attr + */ + u8 ptlv[]; +} NanConfigurationReqMsg, *pNanConfigurationReqMsg; + +/* + * Because the Configuration Req message has TLVs in it use the macro below + * for the size argument to buffer allocation functions (vs. sizeof(msg)). + */ +#define NAN_MAX_CONFIGURATION_REQ_SIZE \ + ( \ + sizeof(NanMsgHeader) + \ + SIZEOF_TLV_HDR + sizeof(u8) /* SID Beacon */ + \ + SIZEOF_TLV_HDR + sizeof(u8) /* Random Time */ + \ + SIZEOF_TLV_HDR + sizeof(u8) /* Master Pref */ \ + ) + +/* NAN Configuration Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanConfigurationRspMsg, *pNanConfigurationRspMsg; + +/* + * Because the Enable Req message has TLVs in it use the macro below for + * the size argument to buffer allocation functions (vs. sizeof(msg)). + */ +#define NAN_MAX_ENABLE_REQ_SIZE \ + ( \ + sizeof(NanMsgHeader) + \ + SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Low */ + \ + SIZEOF_TLV_HDR + sizeof(u16) /* Cluster High */ + \ + SIZEOF_TLV_HDR + sizeof(u8) /* Master Pref */ \ + ) + +/* Config Discovery Indication */ + typedef struct PACKED + { + u32 disableDiscoveryMacAddressEvent:1; + u32 disableDiscoveryStartedClusterEvent:1; + u32 disableDiscoveryJoinedClusterEvent:1; + u32 reserved:29; + } NanConfigDiscoveryIndications; + +/* NAN Enable Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + * TLVs: + * + * Required: Cluster Low, Cluster High, Master Preference, + * Optional: 5G Support, SID, 5G Sync Disc, RSSI Close, RSSI Medium, + * Hop Count Limit, Random Time, Master Preference, + * WLAN Intra Attr, P2P Operation Attr, WLAN IBSS Attr, + * WLAN Mesh Attr + */ + u8 ptlv[]; +} NanEnableReqMsg, *pNanEnableReqMsg; + +/* NAN Enable Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanEnableRspMsg, *pNanEnableRspMsg; + +/* NAN Disable Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; +} NanDisableReqMsg, *pNanDisableReqMsg; + +/* NAN Disable Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 reserved; +} NanDisableRspMsg, *pNanDisableRspMsg; + +/* NAN Disable Ind */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* reason for the termination */ + u16 reason; + u16 reserved; +} NanDisableIndMsg, *pNanDisableIndMsg; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + u8 ptlv[]; +} NanTcaReqMsg, *pNanTcaReqMsg; + +/* NAN TCA Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 value; +} NanTcaRspMsg, *pNanTcaRspMsg; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + * TLVs: + * + * Optional: Cluster size. + */ + u8 ptlv[]; +} NanTcaIndMsg, *pNanTcaIndMsg; + +/* + * Because the TCA Ind message has TLVs in it use the macro below for the + * size argument to buffer allocation functions (vs. sizeof(msg)). + */ +#define NAN_MAX_TCA_IND_SIZE \ + ( \ + sizeof(NanMsgHeader) + \ + sizeof(NanTcaIndParams) + \ + SIZEOF_TLV_HDR + sizeof(u16) /* Cluster Size */ \ + ) + +/* Function Declarations */ +u8* addTlv(u16 type, u16 length, const u8* value, u8* pOutTlv); +u16 NANTLV_ReadTlv(u8 *pInTlv, pNanTlv pOutTlv, int inBufferSize); +u16 NANTLV_WriteTlv(pNanTlv pInTlv, u8 *pOutTlv); + +/* NAN Beacon Sdf Payload Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + * TLVs: + * + * Optional: Vendor specific attribute + */ + u8 ptlv[]; +} NanBeaconSdfPayloadReqMsg, *pNanBeaconSdfPayloadReqMsg; + +/* NAN Beacon Sdf Payload Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u16 status; + u16 reserved; +} NanBeaconSdfPayloadRspMsg, *pNanBeaconSdfPayloadRspMsg; + +/* NAN Beacon Sdf Payload Ind */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + * TLVs: + * + * Required: Mac address + * Optional: Vendor specific attribute, sdf payload + * receive + */ + u8 ptlv[]; +} NanBeaconSdfPayloadIndMsg, *pNanBeaconSdfPayloadIndMsg; + +typedef struct PACKED +{ + u8 availIntDuration:2; + u8 mapId:4; + u8 reserved:2; +} NanApiEntryCtrl; + +/* + * Valid Operating Classes were derived from IEEE Std. 802.11-2012 Annex E + * Table E-4 Global Operating Classe and, filtered by channel, are: 81, 83, + * 84, 103, 114, 115, 116, 124, 125. + */ +typedef struct PACKED +{ + NanApiEntryCtrl entryCtrl; + u8 opClass; + u8 channel; + u8 availIntBitmap[4]; +} NanFurtherAvailabilityChan, *pNanFurtherAvailabilityChan; + +typedef struct PACKED +{ + u8 numChan; + u8 pFaChan[]; +} NanFurtherAvailabilityMapAttrTlv, *pNanFurtherAvailabilityMapAttrTlv; + +/* Publish statistics. */ +typedef struct PACKED +{ + u32 validPublishServiceReqMsgs; + u32 validPublishServiceRspMsgs; + u32 validPublishServiceCancelReqMsgs; + u32 validPublishServiceCancelRspMsgs; + u32 validPublishRepliedIndMsgs; + u32 validPublishTerminatedIndMsgs; + u32 validActiveSubscribes; + u32 validMatches; + u32 validFollowups; + u32 invalidPublishServiceReqMsgs; + u32 invalidPublishServiceCancelReqMsgs; + u32 invalidActiveSubscribes; + u32 invalidMatches; + u32 invalidFollowups; + u32 publishCount; + u32 publishNewMatchCount; + u32 pubsubGlobalNewMatchCount; +} FwNanPublishStats, *pFwNanPublishStats; + +/* Subscribe statistics. */ +typedef struct PACKED +{ + u32 validSubscribeServiceReqMsgs; + u32 validSubscribeServiceRspMsgs; + u32 validSubscribeServiceCancelReqMsgs; + u32 validSubscribeServiceCancelRspMsgs; + u32 validSubscribeTerminatedIndMsgs; + u32 validSubscribeMatchIndMsgs; + u32 validSubscribeUnmatchIndMsgs; + u32 validSolicitedPublishes; + u32 validMatches; + u32 validFollowups; + u32 invalidSubscribeServiceReqMsgs; + u32 invalidSubscribeServiceCancelReqMsgs; + u32 invalidSubscribeFollowupReqMsgs; + u32 invalidSolicitedPublishes; + u32 invalidMatches; + u32 invalidFollowups; + u32 subscribeCount; + u32 bloomFilterIndex; + u32 subscribeNewMatchCount; + u32 pubsubGlobalNewMatchCount; +} FwNanSubscribeStats, *pFwNanSubscribeStats; + +/* NAN MAC Statistics. Used for MAC and DW statistics. */ +typedef struct PACKED +{ + /* RX stats */ + u32 validFrames; + u32 validActionFrames; + u32 validBeaconFrames; + u32 ignoredActionFrames; + u32 ignoredBeaconFrames; + u32 invalidFrames; + u32 invalidActionFrames; + u32 invalidBeaconFrames; + u32 invalidMacHeaders; + u32 invalidPafHeaders; + u32 nonNanBeaconFrames; + + u32 earlyActionFrames; + u32 inDwActionFrames; + u32 lateActionFrames; + + /* TX stats */ + u32 framesQueued; + u32 totalTRSpUpdates; + u32 completeByTRSp; + u32 completeByTp75DW; + u32 completeByTendDW; + u32 lateActionFramesTx; + + /* Misc stats - ignored for DW. */ + u32 twIncreases; + u32 twDecreases; + u32 twChanges; + u32 twHighwater; + u32 bloomFilterIndex; +} FwNanMacStats, *pFwNanMacStats; + +/* NAN Sync and DW Statistics*/ +typedef struct PACKED +{ + u64 currTsf; + u64 myRank; + u64 currAmRank; + u64 lastAmRank; + u32 currAmBTT; + u32 lastAmBTT; + u8 currAmHopCount; + u8 currRole; + u16 currClusterId; + u32 reserved1; + + u64 timeSpentInCurrRole; + u64 totalTimeSpentAsMaster; + u64 totalTimeSpentAsNonMasterSync; + u64 totalTimeSpentAsNonMasterNonSync; + u32 transitionsToAnchorMaster; + u32 transitionsToMaster; + u32 transitionsToNonMasterSync; + u32 transitionsToNonMasterNonSync; + u32 amrUpdateCount; + u32 amrUpdateRankChangedCount; + u32 amrUpdateBTTChangedCount; + u32 amrUpdateHcChangedCount; + u32 amrUpdateNewDeviceCount; + u32 amrExpireCount; + u32 mergeCount; + u32 beaconsAboveHcLimit; + u32 beaconsBelowRssiThresh; + u32 beaconsIgnoredNoSpace; + u32 beaconsForOurCluster; + u32 beaconsForOtherCluster; + u32 beaconCancelRequests; + u32 beaconCancelFailures; + u32 beaconUpdateRequests; + u32 beaconUpdateFailures; + u32 syncBeaconTxAttempts; + u32 syncBeaconTxFailures; + u32 discBeaconTxAttempts; + u32 discBeaconTxFailures; + u32 amHopCountExpireCount; + u32 ndpChannelFreq; + u32 ndpChannelFreq2; + u32 schedUpdateChannelFreq; +} FwNanSyncStats, *pFwNanSyncStats; + +/* NAN Misc DE Statistics */ +typedef struct PACKED +{ + u32 validErrorRspMsgs; + u32 validTransmitFollowupReqMsgs; + u32 validTransmitFollowupRspMsgs; + u32 validFollowupIndMsgs; + u32 validConfigurationReqMsgs; + u32 validConfigurationRspMsgs; + u32 validStatsReqMsgs; + u32 validStatsRspMsgs; + u32 validEnableReqMsgs; + u32 validEnableRspMsgs; + u32 validDisableReqMsgs; + u32 validDisableRspMsgs; + u32 validDisableIndMsgs; + u32 validEventIndMsgs; + u32 validTcaReqMsgs; + u32 validTcaRspMsgs; + u32 validTcaIndMsgs; + u32 invalidTransmitFollowupReqMsgs; + u32 invalidConfigurationReqMsgs; + u32 invalidStatsReqMsgs; + u32 invalidEnableReqMsgs; + u32 invalidDisableReqMsgs; + u32 invalidTcaReqMsgs; +} FwNanDeStats, *pFwNanDeStats; + +/* + Definition of various NanIndication(events) +*/ +typedef enum { + NAN_INDICATION_PUBLISH_REPLIED =0, + NAN_INDICATION_PUBLISH_TERMINATED =1, + NAN_INDICATION_MATCH =2, + NAN_INDICATION_MATCH_EXPIRED =3, + NAN_INDICATION_SUBSCRIBE_TERMINATED =4, + NAN_INDICATION_DE_EVENT =5, + NAN_INDICATION_FOLLOWUP =6, + NAN_INDICATION_DISABLED =7, + NAN_INDICATION_TCA =8, + NAN_INDICATION_BEACON_SDF_PAYLOAD =9, + NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP =10, + NAN_INDICATION_RANGING_REQUEST_RECEIVED =11, + NAN_INDICATION_RANGING_RESULT =12, + NAN_INDICATION_UNKNOWN =0xFFFF +} NanIndicationType; + +/* NAN Capabilities Req */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; +} NanCapabilitiesReqMsg, *pNanCapabilitiesReqMsg; + +/* NAN Capabilities Rsp */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* status of the request */ + u32 status; + u32 value; + u32 max_concurrent_nan_clusters; + u32 max_publishes; + u32 max_subscribes; + u32 max_service_name_len; + u32 max_match_filter_len; + u32 max_total_match_filter_len; + u32 max_service_specific_info_len; + u32 max_vsa_data_len; + u32 max_mesh_data_len; + u32 max_ndi_interfaces; + u32 max_ndp_sessions; + u32 max_app_info_len; + u32 max_queued_transmit_followup_msgs; + u32 ndp_supported_bands; + u32 cipher_suites_supported; + u32 max_scid_len; + u32 is_ndp_security_supported:1; + u32 max_sdea_service_specific_info_len:16; + u32 reserved1:5; + u32 reserved2:5; + u32 ndpe_attr_supported:1; + u32 reserved:4; + u32 max_subscribe_address; +} NanCapabilitiesRspMsg, *pNanCapabilitiesRspMsg; + +/* NAN Self Transmit Followup */ +typedef struct PACKED +{ + NanMsgHeader fwHeader; + u32 reason; +} NanSelfTransmitFollowupIndMsg, *pNanSelfTransmitFollowupIndMsg; + +/* NAN Cipher Suite Shared Key */ +typedef struct PACKED +{ + u32 csid_type; +} NanCsidType; + +/* Service Discovery Extended Attribute params */ +typedef struct PACKED +{ + u32 fsd_required:1; + u32 fsd_with_gas:1; + u32 data_path_required:1; + u32 data_path_type:1; + u32 multicast_type:1; + u32 qos_required:1; + u32 security_required:1; + u32 ranging_required:1; + u32 range_limit_present:1; + u32 service_update_ind_present:1; + u32 reserved1:6; + u32 range_report:1; + u32 reserved2:15; +} NanFWSdeaCtrlParams; + +/* NAN Ranging Configuration params */ +typedef struct PACKED +{ + u32 inner_threshold; + u32 outer_threshold; +} NanFWGeoFenceDescriptor; + +typedef struct PACKED +{ + u32 range_resolution; + u32 range_interval; + u32 ranging_indication_event; + NanFWGeoFenceDescriptor geo_fence_threshold; +} NanFWRangeConfigParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /* + Excludes TLVs + Optional: Nan Availability + */ + u8 ptlv[]; +} NanTestModeReqMsg, *pNanTestModeReqMsg; + +/* + NAN Status codes exchanged between firmware + and WifiHal. +*/ +typedef enum { + /* NAN Protocol Response Codes */ + NAN_I_STATUS_SUCCESS = 0, + NAN_I_STATUS_TIMEOUT = 1, + NAN_I_STATUS_DE_FAILURE = 2, + NAN_I_STATUS_INVALID_MSG_VERSION = 3, + NAN_I_STATUS_INVALID_MSG_LEN = 4, + NAN_I_STATUS_INVALID_MSG_ID = 5, + NAN_I_STATUS_INVALID_HANDLE = 6, + NAN_I_STATUS_NO_SPACE_AVAILABLE = 7, + NAN_I_STATUS_INVALID_PUBLISH_TYPE = 8, + NAN_I_STATUS_INVALID_TX_TYPE = 9, + NAN_I_STATUS_INVALID_MATCH_ALGORITHM = 10, + NAN_I_STATUS_DISABLE_IN_PROGRESS = 11, + NAN_I_STATUS_INVALID_TLV_LEN = 12, + NAN_I_STATUS_INVALID_TLV_TYPE = 13, + NAN_I_STATUS_MISSING_TLV_TYPE = 14, + NAN_I_STATUS_INVALID_TOTAL_TLVS_LEN = 15, + NAN_I_STATUS_INVALID_REQUESTER_INSTANCE_ID= 16, + NAN_I_STATUS_INVALID_TLV_VALUE = 17, + NAN_I_STATUS_INVALID_TX_PRIORITY = 18, + NAN_I_STATUS_INVALID_CONNECTION_MAP = 19, + NAN_I_STATUS_INVALID_THRESHOLD_CROSSING_ALERT_ID = 20, + NAN_I_STATUS_INVALID_STATS_ID = 21, + NAN_I_STATUS_NAN_NOT_ALLOWED = 22, + NAN_I_STATUS_NO_OTA_ACK = 23, + NAN_I_STATUS_TX_FAIL = 24, + NAN_I_STATUS_NAN_ALREADY_ENABLED = 25, + NAN_I_STATUS_FOLLOWUP_QUEUE_FULL = 26, + /* 27-4095 Reserved */ + /* NAN Configuration Response codes */ + NAN_I_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096, + NAN_I_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097, + NAN_I_STATUS_INVALID_HOP_COUNT_LIMIT = 4098, + NAN_I_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099, + NAN_I_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100, + NAN_I_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101, + NAN_I_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102, + NAN_I_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103, + NAN_I_STATUS_INVALID_SCAN_CHANNEL = 4104, + NAN_I_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE = 4106, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE = 4107, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE = 4108, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE = 4109, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110, + NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID = 4111, + NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112, + NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113, + NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114, + NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115, + NAN_I_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116, + NAN_I_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117, + NAN_I_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE = 4118, + NAN_I_STATUS_INVALID_ONGOING_SCAN_PERIOD = 4119, + NAN_I_STATUS_INVALID_DW_INTERVAL_VALUE = 4120, + NAN_I_STATUS_INVALID_DB_INTERVAL_VALUE = 4121, + /* 4122-8191 RESERVED */ + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_INVALID = 8192, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_TIMEOUT = 8193, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_USER_REQUEST = 8194, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_FAILURE = 8195, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_COUNT_REACHED = 8196, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_DE_SHUTDOWN = 8197, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_DISABLE_IN_PROGRESS = 8198, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED = 8199, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200, + NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201, + /* 9000-9500 NDP Status type */ + NDP_I_UNSUPPORTED_CONCURRENCY = 9000, + NDP_I_NAN_DATA_IFACE_CREATE_FAILED = 9001, + NDP_I_NAN_DATA_IFACE_DELETE_FAILED = 9002, + NDP_I_DATA_INITIATOR_REQUEST_FAILED = 9003, + NDP_I_DATA_RESPONDER_REQUEST_FAILED = 9004, + NDP_I_INVALID_SERVICE_INSTANCE_ID = 9005, + NDP_I_INVALID_NDP_INSTANCE_ID = 9006, + NDP_I_INVALID_RESPONSE_CODE = 9007, + NDP_I_INVALID_APP_INFO_LEN = 9008, + /* OTA failures and timeouts during negotiation */ + NDP_I_MGMT_FRAME_REQUEST_FAILED = 9009, + NDP_I_MGMT_FRAME_RESPONSE_FAILED = 9010, + NDP_I_MGMT_FRAME_CONFIRM_FAILED = 9011, + NDP_I_END_FAILED = 9012, + NDP_I_MGMT_FRAME_END_REQUEST_FAILED = 9013, + NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED = 9014, + + /* 9500 onwards vendor specific error codes */ + NDP_I_VENDOR_SPECIFIC_ERROR = 9500 +} NanInternalStatusType; + +/* This is the TLV used for range report */ +typedef struct PACKED +{ + u32 publish_id; + u32 event_type; + u32 range_measurement; +} NanFWRangeReportParams; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /*TLV Required: + MANDATORY + 1. MAC_ADDRESS + 2. NanFWRangeReportParams + OPTIONAL: + 1. A_UINT32 event type + */ + u8 ptlv[1]; +} NanFWRangeReportInd, *pNanFWRangeReportInd; + +/** 2 word representation of MAC addr */ +typedef struct { + /** upper 4 bytes of MAC address */ + u32 mac_addr31to0; + /** lower 2 bytes of MAC address */ + u32 mac_addr47to32; +} fw_mac_addr; + +/* This is the TLV used to trigger ranging requests*/ +typedef struct PACKED +{ + fw_mac_addr range_mac_addr; + u32 range_id; //Match handle in match_ind, publish_id in result ind + u32 ranging_accept:1; + u32 ranging_reject:1; + u32 ranging_cancel:1; + u32 reserved:29; +} NanFWRangeReqMsg, *pNanFWRangeReqMsg; + +typedef struct PACKED +{ + fw_mac_addr range_mac_addr; + u32 range_id;//This will publish_id in case of receiving publish. +} NanFWRangeReqRecvdMsg, *pNanFWRangeReqRecvdMsg; + +typedef struct PACKED +{ + NanMsgHeader fwHeader; + /*TLV Required + 1. t_nan_range_req_recvd_msg + */ + u8 ptlv[1]; +} NanFWRangeReqRecvdInd, *pNanFWRangeReqRecvdInd; + +/* Function for NAN error translation + For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd, + NanDisabledInd, NanTransmitFollowupInd: + function to translate firmware specific errors + to generic freamework error along with the error string +*/ +void NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd, + u32 valueRcvd, + void *pRsp, + bool is_ndp_rsp); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __NAN_I_H__ */ + diff --git a/wcn6740/qcwcn/wifi_hal/nan_ind.cpp b/wcn6740/qcwcn/wifi_hal/nan_ind.cpp new file mode 100644 index 0000000..47ad8f8 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan_ind.cpp @@ -0,0 +1,1452 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "sync.h" +#include <utils/Log.h> +#include <errno.h> +#include "wifi_hal.h" +#include "nan_i.h" +#include "nancommand.h" +#include <errno.h> + +//Function which calls the necessaryIndication callback +//based on the indication type +int NanCommand::handleNanIndication() +{ + //Based on the message_id in the header determine the Indication type + //and call the necessary callback handler + u16 msg_id; + int res = 0; + + msg_id = getIndicationType(); + + ALOGV("handleNanIndication msg_id:%u", msg_id); + switch (msg_id) { + case NAN_INDICATION_PUBLISH_REPLIED: + NanPublishRepliedInd publishRepliedInd; + memset(&publishRepliedInd, 0, sizeof(publishRepliedInd)); + res = getNanPublishReplied(&publishRepliedInd); + if (!res && mHandler.EventPublishReplied) { + (*mHandler.EventPublishReplied)(&publishRepliedInd); + } + break; + + case NAN_INDICATION_PUBLISH_TERMINATED: + NanPublishTerminatedInd publishTerminatedInd; + memset(&publishTerminatedInd, 0, sizeof(publishTerminatedInd)); + res = getNanPublishTerminated(&publishTerminatedInd); + if (!res && mHandler.EventPublishTerminated) { + (*mHandler.EventPublishTerminated)(&publishTerminatedInd); + } + break; + + case NAN_INDICATION_MATCH: + NanMatchInd matchInd; + memset(&matchInd, 0, sizeof(matchInd)); + res = getNanMatch(&matchInd); + if (!res && mHandler.EventMatch) { + (*mHandler.EventMatch)(&matchInd); + } + break; + + case NAN_INDICATION_MATCH_EXPIRED: + NanMatchExpiredInd matchExpiredInd; + memset(&matchExpiredInd, 0, sizeof(matchExpiredInd)); + res = getNanMatchExpired(&matchExpiredInd); + if (!res && mHandler.EventMatchExpired) { + (*mHandler.EventMatchExpired)(&matchExpiredInd); + } + break; + + case NAN_INDICATION_SUBSCRIBE_TERMINATED: + NanSubscribeTerminatedInd subscribeTerminatedInd; + memset(&subscribeTerminatedInd, 0, sizeof(subscribeTerminatedInd)); + res = getNanSubscribeTerminated(&subscribeTerminatedInd); + if (!res && mHandler.EventSubscribeTerminated) { + (*mHandler.EventSubscribeTerminated)(&subscribeTerminatedInd); + } + break; + + case NAN_INDICATION_DE_EVENT: + NanDiscEngEventInd discEngEventInd; + memset(&discEngEventInd, 0, sizeof(discEngEventInd)); + res = getNanDiscEngEvent(&discEngEventInd); + /* Save the self MAC address received in DE indication event to use it + * in Passphrase to PMK calculation. And do not call the handler if the + * framework has disabled the self MAC address indication. + */ + if (!res && + (discEngEventInd.event_type == NAN_EVENT_ID_DISC_MAC_ADDR)) { + mNanCommandInstance->saveNmi(discEngEventInd.data.mac_addr.addr); + if (mNanCommandInstance->mNanDiscAddrIndDisabled) + break; + } + if (!res && mHandler.EventDiscEngEvent) { + (*mHandler.EventDiscEngEvent)(&discEngEventInd); + } + break; + + case NAN_INDICATION_FOLLOWUP: + NanFollowupInd followupInd; + memset(&followupInd, 0, sizeof(followupInd)); + res = getNanFollowup(&followupInd); + if (!res && mHandler.EventFollowup) { + (*mHandler.EventFollowup)(&followupInd); + } + break; + + case NAN_INDICATION_DISABLED: + NanDisabledInd disabledInd; + memset(&disabledInd, 0, sizeof(disabledInd)); + res = getNanDisabled(&disabledInd); + if (!res && mHandler.EventDisabled) { + (*mHandler.EventDisabled)(&disabledInd); + } + break; + + case NAN_INDICATION_TCA: + NanTCAInd tcaInd; + memset(&tcaInd, 0, sizeof(tcaInd)); + res = getNanTca(&tcaInd); + if (!res && mHandler.EventTca) { + (*mHandler.EventTca)(&tcaInd); + } + break; + + case NAN_INDICATION_BEACON_SDF_PAYLOAD: + NanBeaconSdfPayloadInd beaconSdfPayloadInd; + memset(&beaconSdfPayloadInd, 0, sizeof(beaconSdfPayloadInd)); + res = getNanBeaconSdfPayload(&beaconSdfPayloadInd); + if (!res && mHandler.EventBeaconSdfPayload) { + (*mHandler.EventBeaconSdfPayload)(&beaconSdfPayloadInd); + } + break; + + case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP: + NanTransmitFollowupInd transmitFollowupInd; + memset(&transmitFollowupInd, 0, sizeof(NanTransmitFollowupInd)); + res = getNanTransmitFollowupInd(&transmitFollowupInd); + if (!res && mHandler.EventTransmitFollowup) { + (*mHandler.EventTransmitFollowup)(&transmitFollowupInd); + } + break; + + case NAN_INDICATION_RANGING_REQUEST_RECEIVED: + NanRangeRequestInd rangeRequestInd; + memset(&rangeRequestInd, 0, sizeof(NanRangeRequestInd)); + res = getNanRangeRequestReceivedInd(&rangeRequestInd); + if (!res && mHandler.EventRangeRequest) { + (*mHandler.EventRangeRequest)(&rangeRequestInd); + } + break; + + case NAN_INDICATION_RANGING_RESULT: + NanRangeReportInd rangeReportInd; + memset(&rangeReportInd, 0, sizeof(NanRangeReportInd)); + res = getNanRangeReportInd(&rangeReportInd); + if (!res && mHandler.EventRangeReport) { + (*mHandler.EventRangeReport)(&rangeReportInd); + } + break; + + default: + ALOGE("handleNanIndication error invalid msg_id:%u", msg_id); + res = (int)WIFI_ERROR_INVALID_REQUEST_ID; + break; + } + return res; +} + +//Function which will return the Nan Indication type based on +//the initial few bytes of mNanVendorEvent +NanIndicationType NanCommand::getIndicationType() +{ + if (mNanVendorEvent == NULL) { + ALOGE("%s: Invalid argument mNanVendorEvent:%p", + __func__, mNanVendorEvent); + return NAN_INDICATION_UNKNOWN; + } + + NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; + + switch (pHeader->msgId) { + case NAN_MSG_ID_PUBLISH_REPLIED_IND: + return NAN_INDICATION_PUBLISH_REPLIED; + case NAN_MSG_ID_PUBLISH_TERMINATED_IND: + return NAN_INDICATION_PUBLISH_TERMINATED; + case NAN_MSG_ID_MATCH_IND: + return NAN_INDICATION_MATCH; + case NAN_MSG_ID_MATCH_EXPIRED_IND: + return NAN_INDICATION_MATCH_EXPIRED; + case NAN_MSG_ID_FOLLOWUP_IND: + return NAN_INDICATION_FOLLOWUP; + case NAN_MSG_ID_SUBSCRIBE_TERMINATED_IND: + return NAN_INDICATION_SUBSCRIBE_TERMINATED; + case NAN_MSG_ID_DE_EVENT_IND: + return NAN_INDICATION_DE_EVENT; + case NAN_MSG_ID_DISABLE_IND: + return NAN_INDICATION_DISABLED; + case NAN_MSG_ID_TCA_IND: + return NAN_INDICATION_TCA; + case NAN_MSG_ID_BEACON_SDF_IND: + return NAN_INDICATION_BEACON_SDF_PAYLOAD; + case NAN_MSG_ID_SELF_TRANSMIT_FOLLOWUP_IND: + return NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP; + case NAN_MSG_ID_RANGING_REQUEST_RECEVD_IND: + return NAN_INDICATION_RANGING_REQUEST_RECEIVED; + case NAN_MSG_ID_RANGING_RESULT_IND: + return NAN_INDICATION_RANGING_RESULT; + default: + return NAN_INDICATION_UNKNOWN; + } +} + +int NanCommand::getNanPublishReplied(NanPublishRepliedInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanPublishRepliedIndMsg pRsp = (pNanPublishRepliedIndMsg)mNanVendorEvent; + event->requestor_instance_id = pRsp->publishRepliedIndParams.matchHandle; + + event->rssi_value = 0; + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + if (remainingLen <= 0) { + ALOGI("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + switch (outputTlv.type) { + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > sizeof(event->addr)) { + outputTlv.length = sizeof(event->addr); + } + memcpy(event->addr, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: + if (outputTlv.length > sizeof(event->rssi_value)) { + outputTlv.length = sizeof(event->rssi_value); + } + memcpy(&event->rssi_value, outputTlv.value, + outputTlv.length); + break; + default: + ALOGI("Unknown TLV type skipped"); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv, 0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanPublishTerminated(NanPublishTerminatedInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanPublishTerminatedIndMsg pRsp = (pNanPublishTerminatedIndMsg)mNanVendorEvent; + event->publish_id = pRsp->fwHeader.handle; + NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, + (void*)event, false); + return WIFI_SUCCESS; +} + +int NanCommand::getNanMatch(NanMatchInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanMatchIndMsg pRsp = (pNanMatchIndMsg)mNanVendorEvent; + event->publish_subscribe_id = pRsp->fwHeader.handle; + event->requestor_instance_id = pRsp->matchIndParams.matchHandle; + event->match_occured_flag = pRsp->matchIndParams.matchOccuredFlag; + event->out_of_resource_flag = pRsp->matchIndParams.outOfResourceFlag; + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader) + sizeof(NanMatchIndParams))); + int ret = 0, idx = 0; + + //Has SDF match filter and service specific info TLV + if (remainingLen <= 0) { + ALOGV("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: + if (outputTlv.length > NAN_MAX_SERVICE_NAME_LEN) { + outputTlv.length = NAN_MAX_SERVICE_NAME_LEN; + } + event->service_specific_info_len = outputTlv.length; + memcpy(event->service_specific_info, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_SDF_MATCH_FILTER: + if (outputTlv.length > NAN_MAX_MATCH_FILTER_LEN) { + outputTlv.length = NAN_MAX_MATCH_FILTER_LEN; + } + event->sdf_match_filter_len = outputTlv.length; + memcpy(event->sdf_match_filter, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > sizeof(event->addr)) { + outputTlv.length = sizeof(event->addr); + } + memcpy(event->addr, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_RECEIVED_RSSI_VALUE: + if (outputTlv.length > sizeof(event->rssi_value)) { + outputTlv.length = sizeof(event->rssi_value); + } + memcpy(&event->rssi_value, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE: + if (outputTlv.length != sizeof(u32)) { + ALOGE("NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE" + "Incorrect size:%d expecting %zu", outputTlv.length, + sizeof(u32)); + break; + } + event->is_conn_capability_valid = 1; + /* Populate conn_capability from received TLV */ + getNanReceivePostConnectivityCapabilityVal(outputTlv.value, + &event->conn_capability); + break; + case NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE: + /* Populate receive discovery attribute from + received TLV */ + idx = event->num_rx_discovery_attr; + if (idx < 0 || idx >= NAN_MAX_POSTDISCOVERY_LEN) { + ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE" + " Incorrect index:%d >= %d", idx, NAN_MAX_POSTDISCOVERY_LEN); + break; + } + ret = getNanReceivePostDiscoveryVal(outputTlv.value, + outputTlv.length, + &event->discovery_attr[idx]); + if (ret == 0) { + event->num_rx_discovery_attr++; + } else { + ALOGE("NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE" + "Incorrect"); + } + break; + case NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP: + /* Populate further availability bitmap from + received TLV */ + ret = getNanFurtherAvailabilityMap(outputTlv.value, + outputTlv.length, + &event->num_chans, + &event->famchan[0]); + if (ret < 0) + ALOGE("NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP" + "Incorrect"); + break; + case NAN_TLV_TYPE_CLUSTER_ATTRIBUTE: + if (outputTlv.length > sizeof(event->cluster_attribute)) { + outputTlv.length = sizeof(event->cluster_attribute); + } + memcpy(event->cluster_attribute, + outputTlv.value, outputTlv.length); + event->cluster_attribute_len = outputTlv.length; + break; + case NAN_TLV_TYPE_NAN_CSID: + if (outputTlv.length > sizeof(event->peer_cipher_type)) { + outputTlv.length = sizeof(event->peer_cipher_type); + } + memcpy(&event->peer_cipher_type, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_NAN_SCID: + if (outputTlv.length > sizeof(event->scid)) { + outputTlv.length = sizeof(event->scid); + } + event->scid_len = outputTlv.length; + memcpy(event->scid, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_SDEA_CTRL_PARAMS: + if (outputTlv.length != sizeof(u32)) { + ALOGE("NAN_TLV_TYPE_SDEA_CTRL_PARAMS" + "Incorrect size:%d expecting %zu", outputTlv.length, + sizeof(u32)); + break; + } + getNanReceiveSdeaCtrlParams(outputTlv.value, + &event->peer_sdea_params); + break; + case NAN_TLV_TYPE_NAN20_RANGING_RESULT: + if (outputTlv.length > sizeof(event->range_info)) { + outputTlv.length = sizeof(event->range_info); + } + memcpy(&event->range_info, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO: + if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN; + } + event->sdea_service_specific_info_len = outputTlv.length; + memcpy(event->sdea_service_specific_info, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_SERVICE_ID: + mNanCommandInstance->saveServiceId(outputTlv.value, + event->publish_subscribe_id, + event->requestor_instance_id, + NAN_ROLE_SUBSCRIBER); + break; + default: + ALOGV("Unknown TLV type skipped"); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv, 0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanMatchExpired(NanMatchExpiredInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanMatchExpiredIndMsg pRsp = (pNanMatchExpiredIndMsg)mNanVendorEvent; + event->publish_subscribe_id = pRsp->fwHeader.handle; + event->requestor_instance_id = pRsp->matchExpiredIndParams.matchHandle; + return WIFI_SUCCESS; +} + +int NanCommand::getNanSubscribeTerminated(NanSubscribeTerminatedInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanSubscribeTerminatedIndMsg pRsp = (pNanSubscribeTerminatedIndMsg)mNanVendorEvent; + event->subscribe_id = pRsp->fwHeader.handle; + NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, + (void*)event, false); + return WIFI_SUCCESS; +} + +int NanCommand::getNanFollowup(NanFollowupInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanFollowupIndMsg pRsp = (pNanFollowupIndMsg)mNanVendorEvent; + event->publish_subscribe_id = pRsp->fwHeader.handle; + event->requestor_instance_id = pRsp->followupIndParams.matchHandle; + event->dw_or_faw = pRsp->followupIndParams.window; + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader) + sizeof(NanFollowupIndParams))); + + //Has service specific info and extended service specific info TLV + if (remainingLen <= 0) { + ALOGV("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO: + case NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO: + if (outputTlv.length > NAN_MAX_SERVICE_SPECIFIC_INFO_LEN) { + outputTlv.length = NAN_MAX_SERVICE_SPECIFIC_INFO_LEN; + } + event->service_specific_info_len = outputTlv.length; + memcpy(event->service_specific_info, outputTlv.value, + outputTlv.length); + break; + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > sizeof(event->addr)) { + outputTlv.length = sizeof(event->addr); + } + memcpy(event->addr, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO: + if (outputTlv.length > NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN) { + outputTlv.length = NAN_MAX_SDEA_SERVICE_SPECIFIC_INFO_LEN; + } + event->sdea_service_specific_info_len = outputTlv.length; + memcpy(event->sdea_service_specific_info, outputTlv.value, + outputTlv.length); + break; + default: + ALOGV("Unknown TLV type skipped"); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv, 0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanDiscEngEvent(NanDiscEngEventInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanEventIndMsg pRsp = (pNanEventIndMsg)mNanVendorEvent; + memset(&event->data, 0, sizeof(event->data)); + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + //Has Self-STA Mac TLV + if (remainingLen <= 0) { + ALOGE("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS: + if (outputTlv.length > NAN_MAC_ADDR_LEN) { + ALOGV("%s: Reading only first %d bytes of TLV", + __func__, NAN_MAC_ADDR_LEN); + outputTlv.length = NAN_MAC_ADDR_LEN; + } + memcpy(event->data.mac_addr.addr, outputTlv.value, + outputTlv.length); + event->event_type = NAN_EVENT_ID_DISC_MAC_ADDR; + break; + case NAN_TLV_TYPE_EVENT_STARTED_CLUSTER: + if (outputTlv.length > NAN_MAC_ADDR_LEN) { + ALOGV("%s: Reading only first %d bytes of TLV", + __func__, NAN_MAC_ADDR_LEN); + outputTlv.length = NAN_MAC_ADDR_LEN; + } + memcpy(event->data.cluster.addr, outputTlv.value, + outputTlv.length); + event->event_type = NAN_EVENT_ID_STARTED_CLUSTER; + break; + case NAN_TLV_TYPE_EVENT_JOINED_CLUSTER: + if (outputTlv.length > NAN_MAC_ADDR_LEN) { + ALOGV("%s: Reading only first %d bytes of TLV", + __func__, NAN_MAC_ADDR_LEN); + outputTlv.length = NAN_MAC_ADDR_LEN; + } + memcpy(event->data.cluster.addr, outputTlv.value, + outputTlv.length); + event->event_type = NAN_EVENT_ID_JOINED_CLUSTER; + break; + default: + ALOGV("Unhandled TLV type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanDisabled(NanDisabledInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanDisableIndMsg pRsp = (pNanDisableIndMsg)mNanVendorEvent; + NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, + (void*)event, false); + return WIFI_SUCCESS; + +} + +int NanCommand::getNanTca(NanTCAInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanTcaIndMsg pRsp = (pNanTcaIndMsg)mNanVendorEvent; + memset(&event->data, 0, sizeof(event->data)); + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + //Has NAN_TCA_ID_CLUSTER_SIZE + if (remainingLen <= 0) { + ALOGE("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_CLUSTER_SIZE_RSP: + if (outputTlv.length != 2 * sizeof(u32)) { + ALOGE("%s: Wrong length %d in Tca Indication expecting %zu bytes", + __func__, outputTlv.length, 2 * sizeof(u32)); + break; + } + event->rising_direction_evt_flag = outputTlv.value[0] & 0x01; + event->falling_direction_evt_flag = (outputTlv.value[0] & 0x02) >> 1; + memcpy(&(event->data.cluster.cluster_size), &outputTlv.value[4], + sizeof(event->data.cluster.cluster_size)); + event->tca_type = NAN_TCA_ID_CLUSTER_SIZE; + break; + default: + ALOGV("Unhandled TLV type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanBeaconSdfPayloadIndMsg pRsp = (pNanBeaconSdfPayloadIndMsg)mNanVendorEvent; + memset(&event->data, 0, sizeof(event->data)); + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + //Has Mac address + if (remainingLen <= 0) { + ALOGV("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > sizeof(event->addr)) { + outputTlv.length = sizeof(event->addr); + } + memcpy(event->addr, outputTlv.value, + outputTlv.length); + break; + + case NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE: + { + NanReceiveVendorSpecificAttribute* recvVsaattr = &event->vsa; + if (outputTlv.length < sizeof(u32)) { + ALOGE("NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE" + "Incorrect length:%d", outputTlv.length); + break; + } + event->is_vsa_received = 1; + recvVsaattr->vsa_received_on = (outputTlv.value[0] >> 1) & 0x07; + memcpy(&recvVsaattr->vendor_oui, &outputTlv.value[1], + 3); + recvVsaattr->attr_len = outputTlv.length - 4; + if (recvVsaattr->attr_len > NAN_MAX_VSA_DATA_LEN) { + recvVsaattr->attr_len = NAN_MAX_VSA_DATA_LEN; + } + if (recvVsaattr->attr_len) { + memcpy(recvVsaattr->vsa, &outputTlv.value[4], + recvVsaattr->attr_len); + } + break; + } + + case NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE: + event->is_beacon_sdf_payload_received = 1; + event->data.frame_len = outputTlv.length; + if (event->data.frame_len > NAN_MAX_FRAME_DATA_LEN) { + event->data.frame_len = NAN_MAX_FRAME_DATA_LEN; + } + memcpy(&event->data.frame_data, &outputTlv.value[0], + event->data.frame_len); + break; + + default: + ALOGV("Unhandled TLV Type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +void NanCommand::getNanReceivePostConnectivityCapabilityVal( + const u8 *pInValue, + NanReceivePostConnectivityCapability *pRxCapab) +{ + if (pInValue && pRxCapab) { + pRxCapab->is_mesh_supported = (pInValue[0] & (0x01 << 5)); + pRxCapab->is_ibss_supported = (pInValue[0] & (0x01 << 4)); + pRxCapab->wlan_infra_field = (pInValue[0] & (0x01 << 3)); + pRxCapab->is_tdls_supported = (pInValue[0] & (0x01 << 2)); + pRxCapab->is_wfds_supported = (pInValue[0] & (0x01 << 1)); + pRxCapab->is_wfd_supported = pInValue[0] & 0x01; + } +} + +void NanCommand::getNanReceiveSdeaCtrlParams(const u8* pInValue, + NanSdeaCtrlParams *pPeerSdeaParams) +{ + if (pInValue && pPeerSdeaParams) { + pPeerSdeaParams->security_cfg = + (NanDataPathSecurityCfgStatus)((pInValue[0] & BIT_6) ? + NAN_DP_CONFIG_SECURITY : NAN_DP_CONFIG_NO_SECURITY); + pPeerSdeaParams->ranging_state = + (NanRangingState)((pInValue[0] & BIT_7) ? + NAN_RANGING_ENABLE : NAN_RANGING_DISABLE); +#if 0 + pPeerSdeaParams->enable_ranging_limit = + (NanRangingLimitState)((pInValue[0] & BIT_8) ? + NAN_RANGING_LIMIT_ENABLE : NAN_RANGING_LIMIT_DISABLE); +#endif + } + return; +} + +int NanCommand::getNanReceivePostDiscoveryVal(const u8 *pInValue, + u32 length, + NanReceivePostDiscovery *pRxDisc) +{ + int ret = 0; + + if (length <= 8 || pInValue == NULL) { + ALOGE("%s: Invalid Arg TLV Len %d < 4", + __func__, length); + return -1; + } + + pRxDisc->type = (NanConnectionType) pInValue[0]; + pRxDisc->role = (NanDeviceRole) pInValue[1]; + pRxDisc->duration = (NanAvailDuration) (pInValue[2] & 0x03); + pRxDisc->mapid = ((pInValue[2] >> 2) & 0x0F); + memcpy(&pRxDisc->avail_interval_bitmap, + &pInValue[4], + sizeof(pRxDisc->avail_interval_bitmap)); + + u8 *pInputTlv = (u8 *)&pInValue[8]; + NanTlv outputTlv; + u16 readLen = 0; + int remainingLen = (length - 8); + + //Has Mac address + if (remainingLen <= 0) { + ALOGE("%s: No TLV's present",__func__); + return -1; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > sizeof(pRxDisc->addr)) { + outputTlv.length = sizeof(pRxDisc->addr); + } + memcpy(pRxDisc->addr, outputTlv.value, outputTlv.length); + break; + case NAN_TLV_TYPE_WLAN_MESH_ID: + if (outputTlv.length > sizeof(pRxDisc->mesh_id)) { + outputTlv.length = sizeof(pRxDisc->mesh_id); + } + memcpy(pRxDisc->mesh_id, outputTlv.value, outputTlv.length); + pRxDisc->mesh_id_len = outputTlv.length; + break; + case NAN_TLV_TYPE_WLAN_INFRA_SSID: + if (outputTlv.length > sizeof(pRxDisc->infrastructure_ssid_val)) { + outputTlv.length = sizeof(pRxDisc->infrastructure_ssid_val); + } + memcpy(pRxDisc->infrastructure_ssid_val, outputTlv.value, + outputTlv.length); + pRxDisc->infrastructure_ssid_len = outputTlv.length; + break; + default: + ALOGV("Unhandled TLV Type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return ret; +} + +int NanCommand::getNanFurtherAvailabilityMap(const u8 *pInValue, + u32 length, + u8 *num_chans, + NanFurtherAvailabilityChannel *pFac) +{ + int idx = 0; + + if ((length == 0) || pInValue == NULL) { + ALOGE("%s: Invalid Arg TLV Len %d or pInValue NULL", + __func__, length); + return -1; + } + + *num_chans = pInValue[0]; + if (*num_chans > NAN_MAX_FAM_CHANNELS) { + ALOGE("%s: Unable to accommodate numchans %d", + __func__, *num_chans); + return -1; + } + + if (length < (sizeof(u8) + + (*num_chans * sizeof(NanFurtherAvailabilityChan)))) { + ALOGE("%s: Invalid TLV Length", __func__); + return -1; + } + + for (idx = 0; idx < *num_chans; idx++) { + pNanFurtherAvailabilityChan pRsp = \ + (pNanFurtherAvailabilityChan)((u8 *)&pInValue[1] + \ + (idx * sizeof(NanFurtherAvailabilityChan))); + + pFac->entry_control = \ + (NanAvailDuration)(pRsp->entryCtrl.availIntDuration); + pFac->mapid = pRsp->entryCtrl.mapId; + pFac->class_val = pRsp->opClass; + pFac->channel = pRsp->channel; + memcpy(&pFac->avail_interval_bitmap, + &pRsp->availIntBitmap, + sizeof(pFac->avail_interval_bitmap)); + pFac++; + } + return 0; +} + +wifi_error NanCommand::getNanStaParameter(wifi_interface_handle iface, + NanStaParameter *pRsp) +{ + wifi_error ret = WIFI_ERROR_NONE; + transaction_id id = 1; + interface_info *ifaceInfo = getIfaceInfo(iface); + + ret = create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* + Construct NL message to get the sync stats parameter + which has all the parameter required by staparameter. + */ + NanStatsRequest syncStats; + memset(&syncStats, 0, sizeof(syncStats)); + syncStats.stats_type = NAN_STATS_ID_DE_TIMING_SYNC; + syncStats.clear = 0; + + mStaParam = pRsp; + ret = putNanStats(id, &syncStats); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: putNanStats Error:%d",__func__, ret); + goto cleanup; + } + ret = requestEvent(); + if (ret != 0) { + ALOGE("%s: requestEvent Error:%d",__func__, ret); + goto cleanup; + } + + struct timespec abstime; + abstime.tv_sec = 4; + abstime.tv_nsec = 0; + ret = mCondition.wait(abstime); + if (ret == WIFI_ERROR_TIMED_OUT) + { + ALOGE("%s: Time out happened.", __func__); + goto cleanup; + } + ALOGV("%s: NanStaparameter Master_pref:%x," \ + " Random_factor:%x, hop_count:%x " \ + " beacon_transmit_time:%d" \ + " ndp_channel_freq:%d", __func__, + pRsp->master_pref, pRsp->random_factor, + pRsp->hop_count, pRsp->beacon_transmit_time, pRsp->ndp_channel_freq); +cleanup: + mStaParam = NULL; + return ret; +} + +int NanCommand::getNanTransmitFollowupInd(NanTransmitFollowupInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanSelfTransmitFollowupIndMsg pRsp = (pNanSelfTransmitFollowupIndMsg)mNanVendorEvent; + event->id = pRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pRsp->reason, 0, + (void*)event, false); + return WIFI_SUCCESS; +} + +//Function which calls the necessaryIndication callback +//based on the indication type +int NanCommand::handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor) +{ + //Based on the message_id in the header determine the Indication type + //and call the necessary callback handler + int res = 0; + + ALOGI("handleNdpIndication msg_id:%u", ndpCmdType); + switch (ndpCmdType) { + case QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND: + NanDataPathRequestInd ndpRequestInd; + memset(&ndpRequestInd, 0, sizeof(ndpRequestInd)); + + res = getNdpRequest(tb_vendor, &ndpRequestInd); + if (!res && mHandler.EventDataRequest) { + (*mHandler.EventDataRequest)(&ndpRequestInd); + } + break; + + case QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND: + NanDataPathConfirmInd ndpConfirmInd; + memset(&ndpConfirmInd, 0, sizeof(ndpConfirmInd)); + + res = getNdpConfirm(tb_vendor, &ndpConfirmInd); + if (!res && mHandler.EventDataConfirm) { + (*mHandler.EventDataConfirm)(&ndpConfirmInd); + } + break; + + case QCA_WLAN_VENDOR_ATTR_NDP_END_IND: + { + NanDataPathEndInd *ndpEndInd = NULL; + u8 num_ndp_ids = 0; + u8 i; + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32)); + ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids); + + if (num_ndp_ids) { + ndpEndInd = + (NanDataPathEndInd *)malloc(sizeof(NanDataPathEndInd)+ (sizeof(u32) * num_ndp_ids)); + if (!ndpEndInd) { + ALOGE("%s: ndp_instance_id malloc Failed", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + ndpEndInd->num_ndp_instances = num_ndp_ids; + nla_memcpy(ndpEndInd->ndp_instance_id, + tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY], + sizeof(u32) * ndpEndInd->num_ndp_instances); + } + for (i = 0; i < num_ndp_ids; i++) { + mNanCommandInstance->deleteServiceId(0, + ndpEndInd->ndp_instance_id[i], + NAN_ROLE_PUBLISHER); + } + if (mHandler.EventDataEnd) { + (*mHandler.EventDataEnd)(ndpEndInd); + } + free(ndpEndInd); + break; + } + + case QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND: + { + NanDataPathScheduleUpdateInd *pNdpScheduleUpdateInd; + u32 num_channels = 0, num_ndp_ids = 0; + + if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) { + num_channels = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]); + ALOGD("%s: num_channels = %d", __FUNCTION__, num_channels); + if ((num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) && + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + } + num_ndp_ids = (u8)(nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY])/sizeof(u32)); + ALOGD("%s: NDP Num Instance Ids : val %d", __FUNCTION__, num_ndp_ids); + + pNdpScheduleUpdateInd = + (NanDataPathScheduleUpdateInd *)malloc(sizeof(NanDataPathScheduleUpdateInd) + + (sizeof(u32) * num_ndp_ids)); + if (!pNdpScheduleUpdateInd) { + ALOGE("%s: NdpScheduleUpdate malloc Failed", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + pNdpScheduleUpdateInd->num_channels = num_channels; + pNdpScheduleUpdateInd->num_ndp_instances = num_ndp_ids; + + res = getNdpScheduleUpdate(tb_vendor, pNdpScheduleUpdateInd); + if (!res && mHandler.EventScheduleUpdate) { + (*mHandler.EventScheduleUpdate)(pNdpScheduleUpdateInd); + } + free(pNdpScheduleUpdateInd); + break; + } + default: + ALOGE("handleNdpIndication error invalid ndpCmdType:%u", ndpCmdType); + res = (int)WIFI_ERROR_INVALID_REQUEST_ID; + break; + } + return res; +} + +int NanCommand::getNdpRequest(struct nlattr **tb_vendor, + NanDataPathRequestInd *event) +{ + u32 len = 0; + + if (event == NULL || tb_vendor == NULL) { + ALOGE("%s: Invalid input argument event:%p tb_vendor:%p", + __FUNCTION__, event, tb_vendor); + return WIFI_ERROR_INVALID_ARGS; + } + if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID])) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + event->service_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]); + ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->service_instance_id); + + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]); + len = ((sizeof(event->peer_disc_mac_addr) <= len) ? sizeof(event->peer_disc_mac_addr) : len); + memcpy(&event->peer_disc_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len); + + event->ndp_instance_id = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + ALOGD("%s: Ndp Instance id: %d", __FUNCTION__, event->ndp_instance_id); + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len); + memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len); + event->app_info.ndp_app_info_len = len; + } else { + ALOGD("%s: NDP App Info not present", __FUNCTION__); + } + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]) { + mNanCommandInstance->saveServiceId((u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID]), + event->service_instance_id, + event->ndp_instance_id, + NAN_ROLE_PUBLISHER); + } else { + ALOGD("%s: Service ID not present", __FUNCTION__); + } + + return WIFI_SUCCESS; +} + +int NanCommand::getNdpConfirm(struct nlattr **tb_vendor, + NanDataPathConfirmInd *event) +{ + u32 len = 0; + NanInternalStatusType drv_reason_code; + struct nlattr *chInfo; + NanChannelInfo *pChInfo; + int rem; + u32 i = 0; + + if (event == NULL || tb_vendor == NULL) { + ALOGE("%s: Invalid input argument event:%p tb_vendor:%p", + __FUNCTION__, event, tb_vendor); + return WIFI_ERROR_INVALID_ARGS; + } + if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE])) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + event->ndp_instance_id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + ALOGD("%s: Service Instance id : val %d", __FUNCTION__, event->ndp_instance_id); + + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]); + len = ((sizeof(event->peer_ndi_mac_addr) <= len) ? sizeof(event->peer_ndi_mac_addr) : len); + memcpy(&event->peer_ndi_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR]), len); + + event->rsp_code = (NanDataPathResponseCode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); + ALOGD("%s: Response code %d", __FUNCTION__, event->rsp_code); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + len = ((sizeof(event->app_info.ndp_app_info) <= len) ? sizeof(event->app_info.ndp_app_info) : len); + memcpy(&event->app_info.ndp_app_info[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]), len); + event->app_info.ndp_app_info_len = len; + } else { + ALOGD("%s: NDP App Info not present", __FUNCTION__); + } + drv_reason_code = (NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]); + ALOGD("%s: Drv reason code %d", __FUNCTION__, drv_reason_code); + switch (drv_reason_code) { + case NDP_I_MGMT_FRAME_REQUEST_FAILED: + case NDP_I_MGMT_FRAME_RESPONSE_FAILED: + case NDP_I_MGMT_FRAME_CONFIRM_FAILED: + case NDP_I_MGMT_FRAME_END_REQUEST_FAILED: + case NDP_I_MGMT_FRAME_SECURITY_INSTALL_FAILED: + event->reason_code = NAN_STATUS_PROTOCOL_FAILURE; + break; + case NDP_I_END_FAILED: + event->reason_code = NAN_STATUS_INTERNAL_FAILURE; + break; + default: + event->reason_code = (NanStatusType)drv_reason_code; + break; + } + ALOGD("%s: Reason code %d", __FUNCTION__, event->reason_code); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]) { + event->num_channels = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS]); + ALOGD("%s: num_channels = %d", __FUNCTION__, event->num_channels); + if ((event->num_channels > NAN_MAX_CHANNEL_INFO_SUPPORTED) && + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO])) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + } + + if (event->num_channels != 0) { + for (chInfo = + (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]), + rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]); + (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem)); + chInfo = nla_next(chInfo, &(rem))) { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; + + pChInfo = + (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo)))); + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, + (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); + ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]); + ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]); + ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss); + } + } + return WIFI_SUCCESS; +} + +int NanCommand::getNdpScheduleUpdate(struct nlattr **tb_vendor, + NanDataPathScheduleUpdateInd *event) +{ + u32 len = 0; + struct nlattr *chInfo; + NanChannelInfo *pChInfo; + int rem; + u32 i = 0; + + len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]); + len = ((sizeof(event->peer_mac_addr) <= len) ? sizeof(event->peer_mac_addr) : len); + memcpy(&event->peer_mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), len); + + event->schedule_update_reason_code = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON]); + ALOGD("%s: Reason code %d", __FUNCTION__, event->schedule_update_reason_code); + + if (event->num_channels != 0) { + for (chInfo = + (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]), + rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO]); + (i < NAN_MAX_CHANNEL_INFO_SUPPORTED && nla_ok(chInfo, rem)); + chInfo = nla_next(chInfo, &(rem))) { + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1]; + + pChInfo = + (NanChannelInfo *) ((u8 *)event->channel_info + (i++ * (sizeof(NanChannelInfo)))); + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX, + (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_CHANNEL not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->channel = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); + ALOGD("%s: Channel = %d", __FUNCTION__, pChInfo->channel); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->bandwidth = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH]); + ALOGD("%s: Channel BW = %d", __FUNCTION__, pChInfo->bandwidth); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]) { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP_NSS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + pChInfo->nss = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_NDP_NSS]); + ALOGD("%s: No. Spatial Stream = %d", __FUNCTION__, pChInfo->nss); + } + } + + if (event->num_ndp_instances) { + nla_memcpy(event->ndp_instance_id, + tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY], + sizeof(u32) * event->num_ndp_instances); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanRangeRequestReceivedInd(NanRangeRequestInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanFWRangeReqRecvdInd pRsp = (pNanFWRangeReqRecvdInd)mNanVendorEvent; + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + if (remainingLen <= 0) { + ALOGE("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_NAN20_RANGING_REQUEST_RECEIVED: + NanFWRangeReqRecvdMsg fwRangeReqRecvd; + if (outputTlv.length > sizeof(fwRangeReqRecvd)) { + outputTlv.length = sizeof(fwRangeReqRecvd); + } + memcpy(&fwRangeReqRecvd, outputTlv.value, outputTlv.length); + FW_MAC_ADDR_TO_CHAR_ARRAY(fwRangeReqRecvd.range_mac_addr, event->range_req_intf_addr); + event->publish_id = fwRangeReqRecvd.range_id; + break; + default: + ALOGV("Unhandled TLV type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} + +int NanCommand::getNanRangeReportInd(NanRangeReportInd *event) +{ + if (event == NULL || mNanVendorEvent == NULL) { + ALOGE("%s: Invalid input argument event:%p mNanVendorEvent:%p", + __func__, event, mNanVendorEvent); + return WIFI_ERROR_INVALID_ARGS; + } + + pNanFWRangeReportInd pRsp = (pNanFWRangeReportInd)mNanVendorEvent; + + u8 *pInputTlv = pRsp->ptlv; + NanTlv outputTlv; + u16 readLen = 0; + + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader))); + + if (remainingLen <= 0) { + ALOGE("%s: No TLV's present",__func__); + return WIFI_SUCCESS; + } + + ALOGV("%s: TLV remaining Len:%d",__func__, remainingLen); + while ((remainingLen > 0) && + (0 != (readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen)))) { + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + switch (outputTlv.type) { + case NAN_TLV_TYPE_MAC_ADDRESS: + if (outputTlv.length > NAN_MAC_ADDR_LEN) { + outputTlv.length = NAN_MAC_ADDR_LEN; + } + memcpy(event->range_req_intf_addr, outputTlv.value, outputTlv.length); + break; + + case NAN_TLV_TYPE_NAN20_RANGING_RESULT: + NanFWRangeReportParams range_params; + if (outputTlv.length > sizeof(NanFWRangeReportParams)) { + outputTlv.length = sizeof(NanFWRangeReportParams); + } + memcpy(&range_params, outputTlv.value, outputTlv.length); + event->range_measurement_mm = range_params.range_measurement; + event->publish_id = range_params.publish_id; +// event->event_type = range_params.event_type; + break; + default: + ALOGV("Unhandled TLV type:%d", outputTlv.type); + break; + } + remainingLen -= readLen; + pInputTlv += readLen; + memset(&outputTlv,0, sizeof(outputTlv)); + } + return WIFI_SUCCESS; +} diff --git a/wcn6740/qcwcn/wifi_hal/nan_req.cpp b/wcn6740/qcwcn/wifi_hal/nan_req.cpp new file mode 100644 index 0000000..f5c425b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan_req.cpp @@ -0,0 +1,2028 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "sync.h" +#include <utils/Log.h> +#include "wifi_hal.h" +#include "nan_i.h" +#include "nancommand.h" + +wifi_error NanCommand::putNanEnable(transaction_id id, const NanEnableRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_ENABLE"); + size_t message_len = NAN_MAX_ENABLE_REQ_SIZE; + int freq_24g; + + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (pReq->config_24g_channel == 0) + freq_24g = 2437; + else + freq_24g = pReq->channel_24g_val; + + message_len += \ + ( + pReq->config_support_5g ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->support_5g_val)) : 0 \ + ) + \ + ( + pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->sid_beacon_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_rssi_close ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_close_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_rssi_middle ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_middle_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_hop_count_limit ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->hop_count_limit_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_support ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->support_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_beacons ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->beacon_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_sdf ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->sdf_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_5g_beacons ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->beacon_5g_val)) : 0 \ + ) + \ + ( + pReq->config_5g_sdf ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->sdf_5g_val)) : 0 \ + ) + \ + ( + pReq->config_5g_rssi_close ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_close_5g_val)) : 0 \ + ) + \ + ( + pReq->config_5g_rssi_middle ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_middle_5g_val)) : 0 \ + ) + \ + ( + pReq->config_2dot4g_rssi_proximity ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_proximity_2dot4g_val)) : 0 \ + ) + \ + ( + pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ + ) + \ + ( + pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_window_size_val)) : 0 \ + ) + \ + ( + pReq->config_oui ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->oui_val)) : 0 \ + ) + \ + ( + pReq->config_intf_addr ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->intf_addr_val)) : 0 \ + ) + \ + ( + pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->config_cluster_attribute_val)) : 0 \ + ) + \ + ( + pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS * + (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->random_factor_force_val)) : 0 \ + ) + \ + ( + pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->hop_count_force_val)) : 0 \ + ) + \ + ( + /* always include 24g channel/freq */ + SIZEOF_TLV_HDR + sizeof(u32) \ + ) + \ + ( + pReq->config_5g_channel ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + /* Always include cfg discovery indication TLV */ + SIZEOF_TLV_HDR + sizeof(u32) \ + ) + \ + ( + pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->subscribe_sid_beacon_val)) : 0 \ + ) + \ + ( + pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_nss ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ); + + pNanEnableReqMsg pFwReq = (pNanEnableReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_ENABLE_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + u8* tlvs = pFwReq->ptlv; + + /* Write the TLVs to the message. */ + + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_LOW, sizeof(pReq->cluster_low), + (const u8*)&pReq->cluster_low, tlvs); + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ID_HIGH, sizeof(pReq->cluster_high), + (const u8*)&pReq->cluster_high, tlvs); + tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), + (const u8*)&pReq->master_pref, tlvs); + if (pReq->config_support_5g) { + tlvs = addTlv(NAN_TLV_TYPE_5G_SUPPORT, sizeof(pReq->support_5g_val), + (const u8*)&pReq->support_5g_val, tlvs); + } + if (pReq->config_sid_beacon) { + tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon_val), + (const u8*)&pReq->sid_beacon_val, tlvs); + } + if (pReq->config_2dot4g_rssi_close) { + tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE, + sizeof(pReq->rssi_close_2dot4g_val), + (const u8*)&pReq->rssi_close_2dot4g_val, tlvs); + } + if (pReq->config_2dot4g_rssi_middle) { + tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_MIDDLE, + sizeof(pReq->rssi_middle_2dot4g_val), + (const u8*)&pReq->rssi_middle_2dot4g_val, tlvs); + } + if (pReq->config_hop_count_limit) { + tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_LIMIT, + sizeof(pReq->hop_count_limit_val), + (const u8*)&pReq->hop_count_limit_val, tlvs); + } + if (pReq->config_2dot4g_support) { + tlvs = addTlv(NAN_TLV_TYPE_24G_SUPPORT, sizeof(pReq->support_2dot4g_val), + (const u8*)&pReq->support_2dot4g_val, tlvs); + } + if (pReq->config_2dot4g_beacons) { + tlvs = addTlv(NAN_TLV_TYPE_24G_BEACON, sizeof(pReq->beacon_2dot4g_val), + (const u8*)&pReq->beacon_2dot4g_val, tlvs); + } + if (pReq->config_2dot4g_sdf) { + tlvs = addTlv(NAN_TLV_TYPE_24G_SDF, sizeof(pReq->sdf_2dot4g_val), + (const u8*)&pReq->sdf_2dot4g_val, tlvs); + } + if (pReq->config_5g_beacons) { + tlvs = addTlv(NAN_TLV_TYPE_5G_BEACON, sizeof(pReq->beacon_5g_val), + (const u8*)&pReq->beacon_5g_val, tlvs); + } + if (pReq->config_5g_sdf) { + tlvs = addTlv(NAN_TLV_TYPE_5G_SDF, sizeof(pReq->sdf_5g_val), + (const u8*)&pReq->sdf_5g_val, tlvs); + } + if (pReq->config_2dot4g_rssi_proximity) { + tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, + sizeof(pReq->rssi_proximity_2dot4g_val), + (const u8*)&pReq->rssi_proximity_2dot4g_val, tlvs); + } + /* Add the support of sending 5G RSSI values */ + if (pReq->config_5g_rssi_close) { + tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE, sizeof(pReq->rssi_close_5g_val), + (const u8*)&pReq->rssi_close_5g_val, tlvs); + } + if (pReq->config_5g_rssi_middle) { + tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_MIDDLE, sizeof(pReq->rssi_middle_5g_val), + (const u8*)&pReq->rssi_middle_5g_val, tlvs); + } + if (pReq->config_5g_rssi_close_proximity) { + tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, + sizeof(pReq->rssi_close_proximity_5g_val), + (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); + } + if (pReq->config_rssi_window_size) { + tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), + (const u8*)&pReq->rssi_window_size_val, tlvs); + } + if (pReq->config_oui) { + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, sizeof(pReq->oui_val), + (const u8*)&pReq->oui_val, tlvs); + } + if (pReq->config_intf_addr) { + tlvs = addTlv(NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, sizeof(pReq->intf_addr_val), + (const u8*)&pReq->intf_addr_val[0], tlvs); + } + if (pReq->config_cluster_attribute_val) { + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), + (const u8*)&pReq->config_cluster_attribute_val, tlvs); + } + if (pReq->config_scan_params) { + u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; + /* Fill the social channel param */ + fillNanSocialChannelParamVal(&pReq->scan_params_val, + socialChannelParamVal); + int i; + for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { + tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, + sizeof(socialChannelParamVal[i]), + (const u8*)&socialChannelParamVal[i], tlvs); + } + } + if (pReq->config_random_factor_force) { + tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + sizeof(pReq->random_factor_force_val), + (const u8*)&pReq->random_factor_force_val, tlvs); + } + if (pReq->config_hop_count_force) { + tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, + sizeof(pReq->hop_count_force_val), + (const u8*)&pReq->hop_count_force_val, tlvs); + } + tlvs = addTlv(NAN_TLV_TYPE_24G_CHANNEL, + sizeof(u32), + (const u8*)&freq_24g, tlvs); + if (pReq->config_5g_channel) { + tlvs = addTlv(NAN_TLV_TYPE_5G_CHANNEL, + sizeof(u32), + (const u8*)&pReq->channel_5g_val, tlvs); + } + if (pReq->config_dw.config_2dot4g_dw_band) { + tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW, + sizeof(pReq->config_dw.dw_2dot4g_interval_val), + (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs); + } + if (pReq->config_dw.config_5g_dw_band) { + tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW, + sizeof(pReq->config_dw.dw_5g_interval_val), + (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs); + } + if (pReq->config_disc_mac_addr_randomization) { + tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, + sizeof(u32), + (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs); + } + + u32 config_discovery_indications; + config_discovery_indications = (u32)pReq->discovery_indication_cfg; + /* Save the discovery MAC indication config if it is disabled from the + * framework and use it later to decide if the framework to be notified of + * the response. And enable the self MAC discovery indication from firmware + * by resetting the bit in config to get the Self MAC. + */ + if (config_discovery_indications & NAN_DISC_ADDR_IND_DISABLED) { + mNanCommandInstance->mNanDiscAddrIndDisabled = true; + config_discovery_indications &= ~NAN_DISC_ADDR_IND_DISABLED; + } else { + mNanCommandInstance->mNanDiscAddrIndDisabled = false; + } + tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS, + sizeof(u32), + (const u8*)&config_discovery_indications, tlvs); + + if (pReq->config_subscribe_sid_beacon) { + tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON, + sizeof(pReq->subscribe_sid_beacon_val), + (const u8*)&pReq->subscribe_sid_beacon_val, tlvs); + } + if (pReq->config_discovery_beacon_int) { + tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32), + (const u8*)&pReq->discovery_beacon_interval, tlvs); + } + if (pReq->config_nss) { + tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32), + (const u8*)&pReq->nss, tlvs); + } + if (pReq->config_enable_ranging) { + tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32), + (const u8*)&pReq->enable_ranging, tlvs); + } + if (pReq->config_dw_early_termination) { + tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32), + (const u8*)&pReq->enable_dw_termination, tlvs); + } + + mVendorData = (char*)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + //Insert the vendor specific data + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE, + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ) || + mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ, + freq_24g)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (pReq->config_5g_channel) { + if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ, + pReq->channel_5g_val)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanDisable(transaction_id id) +{ + wifi_error ret; + ALOGV("NAN_DISABLE"); + size_t message_len = sizeof(NanDisableReqMsg); + + pNanDisableReqMsg pFwReq = (pNanDisableReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_DISABLE_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + mVendorData = (char*)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_u32(QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE, + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ) || + mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanConfig(transaction_id id, const NanConfigRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_CONFIG"); + size_t message_len = 0; + int idx = 0; + + if (pReq == NULL || + pReq->num_config_discovery_attr > NAN_MAX_POSTDISCOVERY_LEN) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + message_len = sizeof(NanMsgHeader); + + message_len += \ + ( + pReq->config_sid_beacon ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->sid_beacon)) : 0 \ + ) + \ + ( + pReq->config_master_pref ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->master_pref)) : 0 \ + ) + \ + ( + pReq->config_rssi_proximity ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_proximity)) : 0 \ + ) + \ + ( + pReq->config_5g_rssi_close_proximity ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_close_proximity_5g_val)) : 0 \ + ) + \ + ( + pReq->config_rssi_window_size ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->rssi_window_size_val)) : 0 \ + ) + \ + ( + pReq->config_cluster_attribute_val ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->config_cluster_attribute_val)) : 0 \ + ) + \ + ( + pReq->config_scan_params ? NAN_MAX_SOCIAL_CHANNELS * + (SIZEOF_TLV_HDR + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_random_factor_force ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->random_factor_force_val)) : 0 \ + ) + \ + ( + pReq->config_hop_count_force ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->hop_count_force_val)) : 0 \ + ) + \ + ( + pReq->config_conn_capability ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw.config_2dot4g_dw_band ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw.config_5g_dw_band ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_disc_mac_addr_randomization ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_subscribe_sid_beacon ? (SIZEOF_TLV_HDR + \ + sizeof(pReq->subscribe_sid_beacon_val)) : 0 \ + ) + \ + ( + /* Always include cfg discovery indication TLV */ + SIZEOF_TLV_HDR + sizeof(u32) \ + ) + \ + ( + pReq->config_discovery_beacon_int ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_nss ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_enable_ranging ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ) + \ + ( + pReq->config_dw_early_termination ? (SIZEOF_TLV_HDR + \ + sizeof(u32)) : 0 \ + ); + + if (pReq->num_config_discovery_attr) { + for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { + message_len += SIZEOF_TLV_HDR +\ + calcNanTransmitPostDiscoverySize(&pReq->discovery_attr_val[idx]); + } + } + + if (pReq->config_fam && \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { + message_len += (SIZEOF_TLV_HDR + \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)); + } + + pNanConfigurationReqMsg pFwReq = (pNanConfigurationReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_CONFIGURATION_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + u8* tlvs = pFwReq->ptlv; + if (pReq->config_sid_beacon) { + tlvs = addTlv(NAN_TLV_TYPE_SID_BEACON, sizeof(pReq->sid_beacon), + (const u8*)&pReq->sid_beacon, tlvs); + } + if (pReq->config_master_pref) { + tlvs = addTlv(NAN_TLV_TYPE_MASTER_PREFERENCE, sizeof(pReq->master_pref), + (const u8*)&pReq->master_pref, tlvs); + } + if (pReq->config_rssi_window_size) { + tlvs = addTlv(NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, sizeof(pReq->rssi_window_size_val), + (const u8*)&pReq->rssi_window_size_val, tlvs); + } + if (pReq->config_rssi_proximity) { + tlvs = addTlv(NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, sizeof(pReq->rssi_proximity), + (const u8*)&pReq->rssi_proximity, tlvs); + } + if (pReq->config_5g_rssi_close_proximity) { + tlvs = addTlv(NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, + sizeof(pReq->rssi_close_proximity_5g_val), + (const u8*)&pReq->rssi_close_proximity_5g_val, tlvs); + } + if (pReq->config_cluster_attribute_val) { + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, sizeof(pReq->config_cluster_attribute_val), + (const u8*)&pReq->config_cluster_attribute_val, tlvs); + } + if (pReq->config_scan_params) { + u32 socialChannelParamVal[NAN_MAX_SOCIAL_CHANNELS]; + /* Fill the social channel param */ + fillNanSocialChannelParamVal(&pReq->scan_params_val, + socialChannelParamVal); + int i; + for (i = 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { + tlvs = addTlv(NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, + sizeof(socialChannelParamVal[i]), + (const u8*)&socialChannelParamVal[i], tlvs); + } + } + if (pReq->config_random_factor_force) { + tlvs = addTlv(NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + sizeof(pReq->random_factor_force_val), + (const u8*)&pReq->random_factor_force_val, tlvs); + } + if (pReq->config_hop_count_force) { + tlvs = addTlv(NAN_TLV_TYPE_HOP_COUNT_FORCE, + sizeof(pReq->hop_count_force_val), + (const u8*)&pReq->hop_count_force_val, tlvs); + } + if (pReq->config_conn_capability) { + u32 val = \ + getNanTransmitPostConnectivityCapabilityVal(&pReq->conn_capability_val); + tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, + sizeof(val), (const u8*)&val, tlvs); + } + if (pReq->num_config_discovery_attr) { + for (idx = 0; idx < pReq->num_config_discovery_attr; idx ++) { + fillNanTransmitPostDiscoveryVal(&pReq->discovery_attr_val[idx], + (u8*)(tlvs + SIZEOF_TLV_HDR)); + tlvs = addTlv(NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, + calcNanTransmitPostDiscoverySize( + &pReq->discovery_attr_val[idx]), + (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); + } + } + if (pReq->config_fam && \ + calcNanFurtherAvailabilityMapSize(&pReq->fam_val)) { + fillNanFurtherAvailabilityMapVal(&pReq->fam_val, + (u8*)(tlvs + SIZEOF_TLV_HDR)); + tlvs = addTlv(NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, + calcNanFurtherAvailabilityMapSize(&pReq->fam_val), + (const u8*)(tlvs + SIZEOF_TLV_HDR), tlvs); + } + if (pReq->config_dw.config_2dot4g_dw_band) { + tlvs = addTlv(NAN_TLV_TYPE_2G_COMMITTED_DW, + sizeof(pReq->config_dw.dw_2dot4g_interval_val), + (const u8*)&pReq->config_dw.dw_2dot4g_interval_val, tlvs); + } + if (pReq->config_dw.config_5g_dw_band) { + tlvs = addTlv(NAN_TLV_TYPE_5G_COMMITTED_DW, + sizeof(pReq->config_dw.dw_5g_interval_val), + (const u8*)&pReq->config_dw.dw_5g_interval_val, tlvs); + } + if (pReq->config_disc_mac_addr_randomization) { + tlvs = addTlv(NAN_TLV_TYPE_DISC_MAC_ADDR_RANDOM_INTERVAL, + sizeof(u32), + (const u8*)&pReq->disc_mac_addr_rand_interval_sec, tlvs); + } + if (pReq->config_subscribe_sid_beacon) { + tlvs = addTlv(NAN_TLV_TYPE_SUBSCRIBE_SID_BEACON, + sizeof(pReq->subscribe_sid_beacon_val), + (const u8*)&pReq->subscribe_sid_beacon_val, tlvs); + } + if (pReq->config_discovery_beacon_int) { + tlvs = addTlv(NAN_TLV_TYPE_DB_INTERVAL, sizeof(u32), + (const u8*)&pReq->discovery_beacon_interval, tlvs); + } + + u32 config_discovery_indications; + config_discovery_indications = (u32)(pReq->discovery_indication_cfg); + /* Save the discovery MAC indication config if it is disabled from the + * framework and use it later to decide if the framework to be notified of + * the response. And enable the self MAC discovery indication from firmware + * by resetting the bit in config to get the Self MAC. + */ + if (config_discovery_indications & NAN_DISC_ADDR_IND_DISABLED) { + mNanCommandInstance->mNanDiscAddrIndDisabled = true; + config_discovery_indications &= ~NAN_DISC_ADDR_IND_DISABLED; + } else { + mNanCommandInstance->mNanDiscAddrIndDisabled = false; + } + /* Always include the discovery cfg TLV as there is no cfg flag */ + tlvs = addTlv(NAN_TLV_TYPE_CONFIG_DISCOVERY_INDICATIONS, + sizeof(u32), + (const u8*)&config_discovery_indications, tlvs); + + if (pReq->config_nss) { + tlvs = addTlv(NAN_TLV_TYPE_TX_RX_CHAINS, sizeof(u32), + (const u8*)&pReq->nss, tlvs); + } + if (pReq->config_enable_ranging) { + tlvs = addTlv(NAN_TLV_TYPE_ENABLE_DEVICE_RANGING, sizeof(u32), + (const u8*)&pReq->enable_ranging, tlvs); + } + if (pReq->config_dw_early_termination) { + tlvs = addTlv(NAN_TLV_TYPE_DW_EARLY_TERMINATION, sizeof(u32), + (const u8*)&pReq->enable_dw_termination, tlvs); + } + + mVendorData = (char*)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanPublish(transaction_id id, const NanPublishRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_PUBLISH"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + size_t message_len = + sizeof(NanMsgHeader) + sizeof(NanPublishServiceReqParams) + + (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + + (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + + (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + + (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) + + (SIZEOF_TLV_HDR + sizeof(NanServiceAcceptPolicy)) + + (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) + + ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg || + pReq->sdea_params.ranging_state || pReq->sdea_params.range_report || + pReq->sdea_params.qos_cfg) ? + SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) + + ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || + pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ? + SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) + + ((pReq->range_response_cfg.publish_id || + pReq->range_response_cfg.ranging_response) ? + SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) + + (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); + + if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && + (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) + message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN; + else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && + (pReq->key_info.body.passphrase_info.passphrase_len >= + NAN_SECURITY_MIN_PASSPHRASE_LEN) && + (pReq->key_info.body.passphrase_info.passphrase_len <= + NAN_SECURITY_MAX_PASSPHRASE_LEN)) + message_len += SIZEOF_TLV_HDR + + pReq->key_info.body.passphrase_info.passphrase_len; + + pNanPublishServiceReqMsg pFwReq = (pNanPublishServiceReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_REQ; + pFwReq->fwHeader.msgLen = message_len; + if (pReq->publish_id == 0) { + pFwReq->fwHeader.handle = 0xFFFF; + } else { + pFwReq->fwHeader.handle = pReq->publish_id; + } + pFwReq->fwHeader.transactionId = id; + + pFwReq->publishServiceReqParams.ttl = pReq->ttl; + pFwReq->publishServiceReqParams.period = pReq->period; + pFwReq->publishServiceReqParams.replyIndFlag = + (pReq->recv_indication_cfg & BIT_3) ? 0 : 1; + pFwReq->publishServiceReqParams.publishType = pReq->publish_type; + pFwReq->publishServiceReqParams.txType = pReq->tx_type; + + pFwReq->publishServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; + pFwReq->publishServiceReqParams.matchAlg = pReq->publish_match_indicator; + pFwReq->publishServiceReqParams.count = pReq->publish_count; + pFwReq->publishServiceReqParams.connmap = pReq->connmap; + pFwReq->publishServiceReqParams.pubTerminatedIndDisableFlag = + (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; + pFwReq->publishServiceReqParams.pubMatchExpiredIndDisableFlag = + (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; + pFwReq->publishServiceReqParams.followupRxIndDisableFlag = + (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; + + pFwReq->publishServiceReqParams.reserved2 = 0; + + u8* tlvs = pFwReq->ptlv; + if (pReq->service_name_len) { + tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, + (const u8*)&pReq->service_name[0], tlvs); + } + if (pReq->service_specific_info_len) { + tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, + (const u8*)&pReq->service_specific_info[0], tlvs); + } + if (pReq->rx_match_filter_len) { + tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, + (const u8*)&pReq->rx_match_filter[0], tlvs); + } + if (pReq->tx_match_filter_len) { + tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, + (const u8*)&pReq->tx_match_filter[0], tlvs); + } + + /* Pass the Accept policy always */ + tlvs = addTlv(NAN_TLV_TYPE_NAN_SERVICE_ACCEPT_POLICY, sizeof(NanServiceAcceptPolicy), + (const u8*)&pReq->service_responder_policy, tlvs); + + if (pReq->cipher_type) { + NanCsidType pNanCsidType; + pNanCsidType.csid_type = pReq->cipher_type; + tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType), + (const u8*)&pNanCsidType, tlvs); + } + + if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && + (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) { + tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, + pReq->key_info.body.pmk_info.pmk_len, + (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs); + } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && + (pReq->key_info.body.passphrase_info.passphrase_len >= + NAN_SECURITY_MIN_PASSPHRASE_LEN) && + (pReq->key_info.body.passphrase_info.passphrase_len <= + NAN_SECURITY_MAX_PASSPHRASE_LEN)) { + tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE, + pReq->key_info.body.passphrase_info.passphrase_len, + (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0], + tlvs); + } + + if (pReq->sdea_params.config_nan_data_path || + pReq->sdea_params.security_cfg || + pReq->sdea_params.ranging_state || + pReq->sdea_params.range_report || + pReq->sdea_params.qos_cfg) { + NanFWSdeaCtrlParams pNanFWSdeaCtrlParams; + memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams)); + + if (pReq->sdea_params.config_nan_data_path) { + pNanFWSdeaCtrlParams.data_path_required = 1; + pNanFWSdeaCtrlParams.data_path_type = + (pReq->sdea_params.ndp_type & BIT_0) ? + NAN_DATA_PATH_MULTICAST_MSG : + NAN_DATA_PATH_UNICAST_MSG; + + } + if (pReq->sdea_params.security_cfg) { + pNanFWSdeaCtrlParams.security_required = + pReq->sdea_params.security_cfg; + } + if (pReq->sdea_params.ranging_state) { + pNanFWSdeaCtrlParams.ranging_required = + pReq->sdea_params.ranging_state; + } + if (pReq->sdea_params.range_report) { + pNanFWSdeaCtrlParams.range_report = + (((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT) >> 1) ? 1 : 0); + } + if (pReq->sdea_params.qos_cfg) { + pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg; + } + tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams), + (const u8*)&pNanFWSdeaCtrlParams, tlvs); + } + + if (pReq->ranging_cfg.ranging_interval_msec || + pReq->ranging_cfg.config_ranging_indications || + pReq->ranging_cfg.distance_ingress_mm || + pReq->ranging_cfg.distance_egress_mm) { + NanFWRangeConfigParams pNanFWRangingCfg; + + memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams)); + pNanFWRangingCfg.range_interval = + pReq->ranging_cfg.ranging_interval_msec; + pNanFWRangingCfg.ranging_indication_event = + ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) | + (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) | + (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)); + + pNanFWRangingCfg.ranging_indication_event = pReq->ranging_cfg.config_ranging_indications; + if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) + pNanFWRangingCfg.geo_fence_threshold.inner_threshold = + pReq->ranging_cfg.distance_ingress_mm; + if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK) + pNanFWRangingCfg.geo_fence_threshold.outer_threshold = + pReq->ranging_cfg.distance_egress_mm; + tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams), + (const u8*)&pNanFWRangingCfg, tlvs); + } + + if (pReq->sdea_service_specific_info_len) { + tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, + (const u8*)&pReq->sdea_service_specific_info[0], tlvs); + } + + if (pReq->range_response_cfg.publish_id || pReq->range_response_cfg.ranging_response) { + + NanFWRangeReqMsg pNanFWRangeReqMsg; + memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg)); + pNanFWRangeReqMsg.range_id = + (u16)pReq->range_response_cfg.publish_id; + CHAR_ARRAY_TO_MAC_ADDR(pReq->range_response_cfg.peer_addr, pNanFWRangeReqMsg.range_mac_addr); + pNanFWRangeReqMsg.ranging_accept = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0); + pNanFWRangeReqMsg.ranging_reject = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0); + pNanFWRangeReqMsg.ranging_cancel = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0); + tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg), + (const u8*)&pNanFWRangeReqMsg, tlvs); + } + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_PUBLISH_CANCEL"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + size_t message_len = sizeof(NanPublishServiceCancelReqMsg); + + pNanPublishServiceCancelReqMsg pFwReq = + (pNanPublishServiceCancelReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.handle = pReq->publish_id; + pFwReq->fwHeader.transactionId = id; + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanSubscribe(transaction_id id, + const NanSubscribeRequest *pReq) +{ + wifi_error ret; + + ALOGV("NAN_SUBSCRIBE"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + size_t message_len = + sizeof(NanMsgHeader) + sizeof(NanSubscribeServiceReqParams) + + (pReq->service_name_len ? SIZEOF_TLV_HDR + pReq->service_name_len : 0) + + (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + pReq->service_specific_info_len : 0) + + (pReq->rx_match_filter_len ? SIZEOF_TLV_HDR + pReq->rx_match_filter_len : 0) + + (pReq->tx_match_filter_len ? SIZEOF_TLV_HDR + pReq->tx_match_filter_len : 0) + + (pReq->cipher_type ? SIZEOF_TLV_HDR + sizeof(NanCsidType) : 0) + + ((pReq->sdea_params.config_nan_data_path || pReq->sdea_params.security_cfg || + pReq->sdea_params.ranging_state || pReq->sdea_params.range_report || + pReq->sdea_params.qos_cfg) ? + SIZEOF_TLV_HDR + sizeof(NanFWSdeaCtrlParams) : 0) + + ((pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || + pReq->ranging_cfg.distance_ingress_mm || pReq->ranging_cfg.distance_egress_mm) ? + SIZEOF_TLV_HDR + sizeof(NanFWRangeConfigParams) : 0) + + ((pReq->range_response_cfg.requestor_instance_id || + pReq->range_response_cfg.ranging_response) ? + SIZEOF_TLV_HDR + sizeof(NanFWRangeReqMsg) : 0) + + (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); + + message_len += \ + (pReq->num_intf_addr_present * (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN)); + + + if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && + (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) + message_len += SIZEOF_TLV_HDR + NAN_PMK_INFO_LEN; + else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && + (pReq->key_info.body.passphrase_info.passphrase_len >= + NAN_SECURITY_MIN_PASSPHRASE_LEN) && + (pReq->key_info.body.passphrase_info.passphrase_len <= + NAN_SECURITY_MAX_PASSPHRASE_LEN)) + message_len += SIZEOF_TLV_HDR + + pReq->key_info.body.passphrase_info.passphrase_len; + + + pNanSubscribeServiceReqMsg pFwReq = (pNanSubscribeServiceReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_REQ; + pFwReq->fwHeader.msgLen = message_len; + if (pReq->subscribe_id == 0) { + pFwReq->fwHeader.handle = 0xFFFF; + } else { + pFwReq->fwHeader.handle = pReq->subscribe_id; + } + pFwReq->fwHeader.transactionId = id; + + pFwReq->subscribeServiceReqParams.ttl = pReq->ttl; + pFwReq->subscribeServiceReqParams.period = pReq->period; + pFwReq->subscribeServiceReqParams.subscribeType = pReq->subscribe_type; + pFwReq->subscribeServiceReqParams.srfAttr = pReq->serviceResponseFilter; + pFwReq->subscribeServiceReqParams.srfInclude = pReq->serviceResponseInclude; + pFwReq->subscribeServiceReqParams.srfSend = pReq->useServiceResponseFilter; + pFwReq->subscribeServiceReqParams.ssiRequired = pReq->ssiRequiredForMatchIndication; + pFwReq->subscribeServiceReqParams.matchAlg = pReq->subscribe_match_indicator; + pFwReq->subscribeServiceReqParams.count = pReq->subscribe_count; + pFwReq->subscribeServiceReqParams.rssiThresholdFlag = pReq->rssi_threshold_flag; + pFwReq->subscribeServiceReqParams.subTerminatedIndDisableFlag = + (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; + pFwReq->subscribeServiceReqParams.subMatchExpiredIndDisableFlag = + (pReq->recv_indication_cfg & BIT_1) ? 1 : 0; + pFwReq->subscribeServiceReqParams.followupRxIndDisableFlag = + (pReq->recv_indication_cfg & BIT_2) ? 1 : 0; + pFwReq->subscribeServiceReqParams.connmap = pReq->connmap; + pFwReq->subscribeServiceReqParams.reserved = 0; + + u8* tlvs = pFwReq->ptlv; + if (pReq->service_name_len) { + tlvs = addTlv(NAN_TLV_TYPE_SERVICE_NAME, pReq->service_name_len, + (const u8*)&pReq->service_name[0], tlvs); + } + if (pReq->service_specific_info_len) { + tlvs = addTlv(NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, pReq->service_specific_info_len, + (const u8*)&pReq->service_specific_info[0], tlvs); + } + if (pReq->rx_match_filter_len) { + tlvs = addTlv(NAN_TLV_TYPE_RX_MATCH_FILTER, pReq->rx_match_filter_len, + (const u8*)&pReq->rx_match_filter[0], tlvs); + } + if (pReq->tx_match_filter_len) { + tlvs = addTlv(NAN_TLV_TYPE_TX_MATCH_FILTER, pReq->tx_match_filter_len, + (const u8*)&pReq->tx_match_filter[0], tlvs); + } + + int i = 0; + for (i = 0; i < pReq->num_intf_addr_present; i++) + { + tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, + NAN_MAC_ADDR_LEN, + (const u8*)&pReq->intf_addr[i][0], tlvs); + } + + if (pReq->cipher_type) { + NanCsidType pNanCsidType; + pNanCsidType.csid_type = pReq->cipher_type; + tlvs = addTlv(NAN_TLV_TYPE_NAN_CSID, sizeof(NanCsidType), + (const u8*)&pNanCsidType, tlvs); + } + + if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PMK) && + (pReq->key_info.body.pmk_info.pmk_len == NAN_PMK_INFO_LEN)) { + tlvs = addTlv(NAN_TLV_TYPE_NAN_PMK, + pReq->key_info.body.pmk_info.pmk_len, + (const u8*)&pReq->key_info.body.pmk_info.pmk[0], tlvs); + } else if ((pReq->key_info.key_type == NAN_SECURITY_KEY_INPUT_PASSPHRASE) && + (pReq->key_info.body.passphrase_info.passphrase_len >= + NAN_SECURITY_MIN_PASSPHRASE_LEN) && + (pReq->key_info.body.passphrase_info.passphrase_len <= + NAN_SECURITY_MAX_PASSPHRASE_LEN)) { + tlvs = addTlv(NAN_TLV_TYPE_NAN_PASSPHRASE, + pReq->key_info.body.passphrase_info.passphrase_len, + (const u8*)&pReq->key_info.body.passphrase_info.passphrase[0], + tlvs); + } + + if (pReq->sdea_params.config_nan_data_path || + pReq->sdea_params.security_cfg || + pReq->sdea_params.ranging_state || + pReq->sdea_params.range_report || + pReq->sdea_params.qos_cfg) { + NanFWSdeaCtrlParams pNanFWSdeaCtrlParams; + memset(&pNanFWSdeaCtrlParams, 0, sizeof(NanFWSdeaCtrlParams)); + + if (pReq->sdea_params.config_nan_data_path) { + pNanFWSdeaCtrlParams.data_path_required = 1; + pNanFWSdeaCtrlParams.data_path_type = + (pReq->sdea_params.ndp_type & BIT_0) ? + NAN_DATA_PATH_MULTICAST_MSG : + NAN_DATA_PATH_UNICAST_MSG; + + } + if (pReq->sdea_params.security_cfg) { + pNanFWSdeaCtrlParams.security_required = + pReq->sdea_params.security_cfg; + } + if (pReq->sdea_params.ranging_state) { + pNanFWSdeaCtrlParams.ranging_required = + pReq->sdea_params.ranging_state; + } + if (pReq->sdea_params.range_report) { + pNanFWSdeaCtrlParams.range_report = + ((pReq->sdea_params.range_report & NAN_ENABLE_RANGE_REPORT >> 1) ? 1 : 0); + } + if (pReq->sdea_params.qos_cfg) { + pNanFWSdeaCtrlParams.qos_required = pReq->sdea_params.qos_cfg; + } + tlvs = addTlv(NAN_TLV_TYPE_SDEA_CTRL_PARAMS, sizeof(NanFWSdeaCtrlParams), + (const u8*)&pNanFWSdeaCtrlParams, tlvs); + + } + + if (pReq->ranging_cfg.ranging_interval_msec || pReq->ranging_cfg.config_ranging_indications || pReq->ranging_cfg.distance_ingress_mm + || pReq->ranging_cfg.distance_egress_mm) { + NanFWRangeConfigParams pNanFWRangingCfg; + memset(&pNanFWRangingCfg, 0, sizeof(NanFWRangeConfigParams)); + pNanFWRangingCfg.range_interval = + pReq->ranging_cfg.ranging_interval_msec; + pNanFWRangingCfg.ranging_indication_event = + ((pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_CONTINUOUS_MASK) | + (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) | + (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK)); + + pNanFWRangingCfg.ranging_indication_event = + pReq->ranging_cfg.config_ranging_indications; + if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_INGRESS_MET_MASK) + pNanFWRangingCfg.geo_fence_threshold.inner_threshold = + pReq->ranging_cfg.distance_ingress_mm; + if (pReq->ranging_cfg.config_ranging_indications & NAN_RANGING_INDICATE_EGRESS_MET_MASK) + pNanFWRangingCfg.geo_fence_threshold.outer_threshold = + pReq->ranging_cfg.distance_egress_mm; + tlvs = addTlv(NAN_TLV_TYPE_NAN_RANGING_CFG, sizeof(NanFWRangeConfigParams), + (const u8*)&pNanFWRangingCfg, tlvs); + } + + if (pReq->sdea_service_specific_info_len) { + tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, + (const u8*)&pReq->sdea_service_specific_info[0], tlvs); + } + + if (pReq->range_response_cfg.requestor_instance_id || pReq->range_response_cfg.ranging_response) { + NanFWRangeReqMsg pNanFWRangeReqMsg; + memset(&pNanFWRangeReqMsg, 0, sizeof(NanFWRangeReqMsg)); + pNanFWRangeReqMsg.range_id = + pReq->range_response_cfg.requestor_instance_id; + memcpy(&pNanFWRangeReqMsg.range_mac_addr, &pReq->range_response_cfg.peer_addr, NAN_MAC_ADDR_LEN); + pNanFWRangeReqMsg.ranging_accept = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_ACCEPT) ? 1 : 0); + pNanFWRangeReqMsg.ranging_reject = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_REJECT) ? 1 : 0); + pNanFWRangeReqMsg.ranging_cancel = + ((pReq->range_response_cfg.ranging_response == NAN_RANGE_REQUEST_CANCEL) ? 1 : 0); + tlvs = addTlv(NAN_TLV_TYPE_NAN20_RANGING_REQUEST, sizeof(NanFWRangeReqMsg), + (const u8*)&pNanFWRangeReqMsg, tlvs); + } + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanSubscribeCancel(transaction_id id, + const NanSubscribeCancelRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_SUBSCRIBE_CANCEL"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + size_t message_len = sizeof(NanSubscribeServiceCancelReqMsg); + + pNanSubscribeServiceCancelReqMsg pFwReq = + (pNanSubscribeServiceCancelReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.handle = pReq->subscribe_id; + pFwReq->fwHeader.transactionId = id; + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanTransmitFollowup(transaction_id id, + const NanTransmitFollowupRequest *pReq) +{ + wifi_error ret; + ALOGV("TRANSMIT_FOLLOWUP"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + size_t message_len = + sizeof(NanMsgHeader) + sizeof(NanTransmitFollowupReqParams) + + (pReq->service_specific_info_len ? SIZEOF_TLV_HDR + + pReq->service_specific_info_len : 0) + + (pReq->sdea_service_specific_info_len ? SIZEOF_TLV_HDR + pReq->sdea_service_specific_info_len : 0); + + /* Mac address needs to be added in TLV */ + message_len += (SIZEOF_TLV_HDR + sizeof(pReq->addr)); + + pNanTransmitFollowupReqMsg pFwReq = (pNanTransmitFollowupReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_TRANSMIT_FOLLOWUP_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.handle = pReq->publish_subscribe_id; + pFwReq->fwHeader.transactionId = id; + + pFwReq->transmitFollowupReqParams.matchHandle = pReq->requestor_instance_id; + if (pReq->priority != NAN_TX_PRIORITY_HIGH) { + pFwReq->transmitFollowupReqParams.priority = 1; + } else { + pFwReq->transmitFollowupReqParams.priority = 2; + } + pFwReq->transmitFollowupReqParams.window = pReq->dw_or_faw; + pFwReq->transmitFollowupReqParams.followupTxRspDisableFlag = + (pReq->recv_indication_cfg & BIT_0) ? 1 : 0; + pFwReq->transmitFollowupReqParams.reserved = 0; + + u8* tlvs = pFwReq->ptlv; + + /* Mac address needs to be added in TLV */ + tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, sizeof(pReq->addr), + (const u8*)&pReq->addr[0], tlvs); + u16 tlv_type = NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO; + + if (pReq->service_specific_info_len) { + tlvs = addTlv(tlv_type, pReq->service_specific_info_len, + (const u8*)&pReq->service_specific_info[0], tlvs); + } + + if (pReq->sdea_service_specific_info_len) { + tlvs = addTlv(NAN_TLV_TYPE_SDEA_SERVICE_SPECIFIC_INFO, pReq->sdea_service_specific_info_len, + (const u8*)&pReq->sdea_service_specific_info[0], tlvs); + } + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanStats(transaction_id id, const NanStatsRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_STATS"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + size_t message_len = sizeof(NanStatsReqMsg); + + pNanStatsReqMsg pFwReq = + (pNanStatsReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_STATS_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + pFwReq->statsReqParams.statsType = pReq->stats_type; + pFwReq->statsReqParams.clear = pReq->clear; + pFwReq->statsReqParams.reserved = 0; + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanTCA(transaction_id id, const NanTCARequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_TCA"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + size_t message_len = sizeof(NanTcaReqMsg); + + message_len += (SIZEOF_TLV_HDR + 2 * sizeof(u32)); + pNanTcaReqMsg pFwReq = + (pNanTcaReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_TCA_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + u32 tcaReqParams[2]; + memset (tcaReqParams, 0, sizeof(tcaReqParams)); + tcaReqParams[0] = (pReq->rising_direction_evt_flag & 0x01); + tcaReqParams[0] |= (pReq->falling_direction_evt_flag & 0x01) << 1; + tcaReqParams[0] |= (pReq->clear & 0x01) << 2; + tcaReqParams[1] = pReq->threshold; + + u8* tlvs = pFwReq->ptlv; + + if (pReq->tca_type == NAN_TCA_ID_CLUSTER_SIZE) { + tlvs = addTlv(NAN_TLV_TYPE_CLUSTER_SIZE_REQ, sizeof(tcaReqParams), + (const u8*)&tcaReqParams[0], tlvs); + } else { + ALOGE("%s: Unrecognized tca_type:%u", __FUNCTION__, pReq->tca_type); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanBeaconSdfPayload(transaction_id id, + const NanBeaconSdfPayloadRequest *pReq) +{ + wifi_error ret; + ALOGV("NAN_BEACON_SDF_PAYLAOD"); + if (pReq == NULL) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + size_t message_len = sizeof(NanMsgHeader) + \ + SIZEOF_TLV_HDR + sizeof(u32) + \ + pReq->vsa.vsa_len; + + pNanBeaconSdfPayloadReqMsg pFwReq = + (pNanBeaconSdfPayloadReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu", message_len); + memset(pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_BEACON_SDF_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + /* Construct First 4 bytes of NanBeaconSdfPayloadReqMsg */ + u32 temp = 0; + temp = pReq->vsa.payload_transmit_flag & 0x01; + temp |= (pReq->vsa.tx_in_discovery_beacon & 0x01) << 1; + temp |= (pReq->vsa.tx_in_sync_beacon & 0x01) << 2; + temp |= (pReq->vsa.tx_in_service_discovery & 0x01) << 3; + temp |= (pReq->vsa.vendor_oui & 0x00FFFFFF) << 8; + + int tlv_len = sizeof(u32) + pReq->vsa.vsa_len; + u8* tempBuf = (u8*)malloc(tlv_len); + if (tempBuf == NULL) { + ALOGE("%s: Malloc failed", __func__); + free(pFwReq); + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + memset(tempBuf, 0, tlv_len); + memcpy(tempBuf, &temp, sizeof(u32)); + memcpy((tempBuf + sizeof(u32)), pReq->vsa.vsa, pReq->vsa.vsa_len); + + u8* tlvs = pFwReq->ptlv; + + /* Write the TLVs to the message. */ + tlvs = addTlv(NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, tlv_len, + (const u8*)tempBuf, tlvs); + free(tempBuf); + + mVendorData = (char *)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +//callback handlers registered for nl message send +static int error_handler_nan(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + struct sockaddr_nl * tmp; + int *ret = (int *)arg; + tmp = nla; + *ret = err->error; + ALOGE("%s: Error code:%d (%s)", __func__, *ret, strerror(-(*ret))); + return NL_STOP; +} + +//callback handlers registered for nl message send +static int ack_handler_nan(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + ALOGE("%s: called", __func__); + a = msg; + *ret = 0; + return NL_STOP; +} + +//callback handlers registered for nl message send +static int finish_handler_nan(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + ALOGE("%s: called", __func__); + a = msg; + *ret = 0; + return NL_SKIP; +} + + +//Override base class requestEvent and implement little differently here +//This will send the request message +//We dont wait for any response back in case of Nan as it is asynchronous +//thus no wait for condition. +wifi_error NanCommand::requestEvent() +{ + wifi_error res; + int status; + struct nl_cb * cb = NULL; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + ALOGE("%s: Callback allocation failed",__func__); + res = WIFI_ERROR_OUT_OF_MEMORY; + goto out; + } + + if (!mInfo->cmd_sock) { + ALOGE("%s: Command socket is null",__func__); + res = WIFI_ERROR_OUT_OF_MEMORY; + goto out; + } + + /* send message */ + ALOGV("%s:Handle:%p Socket Value:%p", __func__, mInfo, mInfo->cmd_sock); + status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + + status = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler_nan, &status); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_nan, &status); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_nan, &status); + + // err is populated as part of finish_handler + while (status > 0) + nl_recvmsgs(mInfo->cmd_sock, cb); + + res = mapKernelErrortoWifiHalError(status); +out: + nl_cb_put(cb); + //free the VendorData + if (mVendorData) { + free(mVendorData); + } + mVendorData = NULL; + //cleanup the mMsg + mMsg.destroy(); + return res; +} + +int NanCommand::calcNanTransmitPostDiscoverySize( + const NanTransmitPostDiscovery *pPostDiscovery) +{ + /* Fixed size of u32 for Conn Type, Device Role and R flag + Dur + Rsvd*/ + int ret = sizeof(u32); + /* size of availability interval bit map is 4 bytes */ + ret += sizeof(u32); + /* size of mac address is 6 bytes*/ + ret += (SIZEOF_TLV_HDR + NAN_MAC_ADDR_LEN); + if (pPostDiscovery && + pPostDiscovery->type == NAN_CONN_WLAN_MESH) { + /* size of WLAN_MESH_ID */ + ret += (SIZEOF_TLV_HDR + \ + pPostDiscovery->mesh_id_len); + } + if (pPostDiscovery && + pPostDiscovery->type == NAN_CONN_WLAN_INFRA) { + /* size of Infrastructure ssid */ + ret += (SIZEOF_TLV_HDR + \ + pPostDiscovery->infrastructure_ssid_len); + } + ALOGV("%s:size:%d", __func__, ret); + return ret; +} + +void NanCommand::fillNanSocialChannelParamVal( + const NanSocialChannelScanParams *pScanParams, + u32* pChannelParamArr) +{ + int i; + if (pChannelParamArr) { + memset(pChannelParamArr, 0, + NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); + for (i= 0; i < NAN_MAX_SOCIAL_CHANNELS; i++) { + pChannelParamArr[i] = pScanParams->scan_period[i] << 16; + pChannelParamArr[i] |= pScanParams->dwell_time[i] << 8; + } + pChannelParamArr[NAN_CHANNEL_24G_BAND] |= 6; + pChannelParamArr[NAN_CHANNEL_5G_BAND_LOW]|= 44; + pChannelParamArr[NAN_CHANNEL_5G_BAND_HIGH]|= 149; + ALOGV("%s: Filled SocialChannelParamVal", __func__); + hexdump((char*)pChannelParamArr, NAN_MAX_SOCIAL_CHANNELS * sizeof(u32)); + } + return; +} + +u32 NanCommand::getNanTransmitPostConnectivityCapabilityVal( + const NanTransmitPostConnectivityCapability *pCapab) +{ + u32 ret = 0; + ret |= (pCapab->payload_transmit_flag? 1:0) << 16; + ret |= (pCapab->is_mesh_supported? 1:0) << 5; + ret |= (pCapab->is_ibss_supported? 1:0) << 4; + ret |= (pCapab->wlan_infra_field? 1:0) << 3; + ret |= (pCapab->is_tdls_supported? 1:0) << 2; + ret |= (pCapab->is_wfds_supported? 1:0) << 1; + ret |= (pCapab->is_wfd_supported? 1:0); + ALOGV("%s: val:%d", __func__, ret); + return ret; +} + +void NanCommand::fillNanTransmitPostDiscoveryVal( + const NanTransmitPostDiscovery *pTxDisc, + u8 *pOutValue) +{ + + if (pTxDisc && pOutValue) { + u8 *tlvs = &pOutValue[8]; + pOutValue[0] = pTxDisc->type; + pOutValue[1] = pTxDisc->role; + pOutValue[2] = (pTxDisc->transmit_freq? 1:0); + pOutValue[2] |= ((pTxDisc->duration & 0x03) << 1); + memcpy(&pOutValue[4], &pTxDisc->avail_interval_bitmap, + sizeof(pTxDisc->avail_interval_bitmap)); + tlvs = addTlv(NAN_TLV_TYPE_MAC_ADDRESS, + NAN_MAC_ADDR_LEN, + (const u8*)&pTxDisc->addr[0], + tlvs); + if (pTxDisc->type == NAN_CONN_WLAN_MESH) { + tlvs = addTlv(NAN_TLV_TYPE_WLAN_MESH_ID, + pTxDisc->mesh_id_len, + (const u8*)&pTxDisc->mesh_id[0], + tlvs); + } + if (pTxDisc->type == NAN_CONN_WLAN_INFRA) { + tlvs = addTlv(NAN_TLV_TYPE_WLAN_INFRA_SSID, + pTxDisc->infrastructure_ssid_len, + (const u8*)&pTxDisc->infrastructure_ssid_val[0], + tlvs); + } + ALOGV("%s: Filled TransmitPostDiscoveryVal", __func__); + hexdump((char*)pOutValue, calcNanTransmitPostDiscoverySize(pTxDisc)); + } + + return; +} + +void NanCommand::fillNanFurtherAvailabilityMapVal( + const NanFurtherAvailabilityMap *pFam, + u8 *pOutValue) +{ + int idx = 0; + + if (pFam && pOutValue) { + u32 famsize = calcNanFurtherAvailabilityMapSize(pFam); + pNanFurtherAvailabilityMapAttrTlv pFwReq = \ + (pNanFurtherAvailabilityMapAttrTlv)pOutValue; + + memset(pOutValue, 0, famsize); + pFwReq->numChan = pFam->numchans; + for (idx = 0; idx < pFam->numchans; idx++) { + const NanFurtherAvailabilityChannel *pFamChan = \ + &pFam->famchan[idx]; + pNanFurtherAvailabilityChan pFwFamChan = \ + (pNanFurtherAvailabilityChan)((u8*)&pFwReq->pFaChan[0] + \ + (idx * sizeof(NanFurtherAvailabilityChan))); + + pFwFamChan->entryCtrl.availIntDuration = \ + pFamChan->entry_control; + pFwFamChan->entryCtrl.mapId = \ + pFamChan->mapid; + pFwFamChan->opClass = pFamChan->class_val; + pFwFamChan->channel = pFamChan->channel; + memcpy(&pFwFamChan->availIntBitmap, + &pFamChan->avail_interval_bitmap, + sizeof(pFwFamChan->availIntBitmap)); + } + ALOGV("%s: Filled FurtherAvailabilityMapVal", __func__); + hexdump((char*)pOutValue, famsize); + } + return; +} + +int NanCommand::calcNanFurtherAvailabilityMapSize( + const NanFurtherAvailabilityMap *pFam) +{ + int ret = 0; + if (pFam && pFam->numchans && + pFam->numchans <= NAN_MAX_FAM_CHANNELS) { + /* Fixed size of u8 for numchans*/ + ret = sizeof(u8); + /* numchans * sizeof(FamChannels) */ + ret += (pFam->numchans * sizeof(NanFurtherAvailabilityChan)); + } + ALOGV("%s:size:%d", __func__, ret); + return ret; +} + +wifi_error NanCommand::putNanCapabilities(transaction_id id) +{ + wifi_error ret; + ALOGV("NAN_CAPABILITIES"); + size_t message_len = sizeof(NanCapabilitiesReqMsg); + + pNanCapabilitiesReqMsg pFwReq = (pNanCapabilitiesReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_CAPABILITIES_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = id; + + mVendorData = (char*)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} + +wifi_error NanCommand::putNanDebugCommand(NanDebugParams debug, + int debug_msg_length) +{ + wifi_error ret; + ALOGV("NAN_AVAILABILITY_DEBUG"); + size_t message_len = sizeof(NanTestModeReqMsg); + + message_len += (SIZEOF_TLV_HDR + debug_msg_length); + pNanTestModeReqMsg pFwReq = (pNanTestModeReqMsg)malloc(message_len); + if (pFwReq == NULL) { + cleanup(); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ALOGV("Message Len %zu\n", message_len); + ALOGV("%s: Debug Command Type = 0x%x \n", __func__, debug.cmd); + ALOGV("%s: ** Debug Command Data Start **", __func__); + hexdump(debug.debug_cmd_data, debug_msg_length); + ALOGV("%s: ** Debug Command Data End **", __func__); + + memset (pFwReq, 0, message_len); + pFwReq->fwHeader.msgVersion = (u16)NAN_MSG_VERSION1; + pFwReq->fwHeader.msgId = NAN_MSG_ID_TESTMODE_REQ; + pFwReq->fwHeader.msgLen = message_len; + pFwReq->fwHeader.transactionId = 0; + + u8* tlvs = pFwReq->ptlv; + tlvs = addTlv(NAN_TLV_TYPE_TESTMODE_GENERIC_CMD, debug_msg_length, + (const u8*)&debug, tlvs); + + mVendorData = (char*)pFwReq; + mDataLen = message_len; + + ret = WIFI_SUCCESS; + if (mSubcmd == QCA_NL80211_VENDOR_SUBCMD_NAN) { + /* Write the TLVs to the message. */ + ret = mMsg.put_bytes(NL80211_ATTR_VENDOR_DATA, mVendorData, mDataLen); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: put_bytes Error:%d",__func__, ret); + cleanup(); + return ret; + } + } else { + struct nlattr *nl_data; + + nl_data = attr_start(NL80211_ATTR_VENDOR_DATA); + + if (!nl_data) { + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + if (mMsg.put_bytes(QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA, + mVendorData, mDataLen)) { + ALOGE("%s: put attr error", __func__); + cleanup(); + return WIFI_ERROR_INVALID_ARGS; + } + attr_end(nl_data); + } + hexdump(mVendorData, mDataLen); + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp b/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp new file mode 100644 index 0000000..060de7f --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nan_rsp.cpp @@ -0,0 +1,1006 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "sync.h" +#include <utils/Log.h> +#include "wifi_hal.h" +#include "nan_i.h" +#include "nancommand.h" + + +int NanCommand::isNanResponse() +{ + if (mNanVendorEvent == NULL) { + ALOGE("NULL check failed"); + return WIFI_ERROR_INVALID_ARGS; + } + + NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; + + switch (pHeader->msgId) { + case NAN_MSG_ID_ERROR_RSP: + case NAN_MSG_ID_CONFIGURATION_RSP: + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + case NAN_MSG_ID_STATS_RSP: + case NAN_MSG_ID_ENABLE_RSP: + case NAN_MSG_ID_DISABLE_RSP: + case NAN_MSG_ID_TCA_RSP: + case NAN_MSG_ID_BEACON_SDF_RSP: + case NAN_MSG_ID_CAPABILITIES_RSP: + case NAN_MSG_ID_TESTMODE_RSP: + return 1; + default: + return 0; + } +} + +struct verboseTlv { + NanTlvType tlvType; + char strTlv[NAN_ERROR_STR_LEN]; +}; + +struct verboseTlv tlvToStr[] = { + {NAN_TLV_TYPE_SDF_MATCH_FILTER, " SDF match filter"}, + {NAN_TLV_TYPE_TX_MATCH_FILTER, " Tx match filter"}, + {NAN_TLV_TYPE_RX_MATCH_FILTER, " Rx match filter"}, + {NAN_TLV_TYPE_SERVICE_SPECIFIC_INFO, + " Service specific info"}, + {NAN_TLV_TYPE_EXT_SERVICE_SPECIFIC_INFO, + " Extended Service specific info"}, + {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_TRANSMIT, + " Vendor specific attribute transmit"}, + {NAN_TLV_TYPE_VENDOR_SPECIFIC_ATTRIBUTE_RECEIVE, + " Vendor specific attribute receive"}, + {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_RECEIVE, + " Post Nan connectivity capability receive"}, + {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_RECEIVE, + " Post Nan discovery attribute receive"}, + {NAN_TLV_TYPE_BEACON_SDF_PAYLOAD_RECEIVE, + " Beacon SDF payload receive"}, + + /* Configuration types */ + {NAN_TLV_TYPE_CONFIG_FIRST, " Config first"}, + {NAN_TLV_TYPE_24G_SUPPORT, " 2.4G support"}, + {NAN_TLV_TYPE_24G_BEACON, " 2.4G beacon"}, + {NAN_TLV_TYPE_24G_SDF, " 2.4G SDF"}, + {NAN_TLV_TYPE_24G_RSSI_CLOSE, " 2.4G RSSI close"}, + {NAN_TLV_TYPE_24G_RSSI_MIDDLE, " 2.4G RSSI middle"}, + {NAN_TLV_TYPE_24G_RSSI_CLOSE_PROXIMITY, + " 2.4G RSSI close proximity"}, + {NAN_TLV_TYPE_5G_SUPPORT, " 5G support"}, + {NAN_TLV_TYPE_5G_BEACON, " 5G beacon"}, + {NAN_TLV_TYPE_5G_SDF, " 5G SDF"}, + {NAN_TLV_TYPE_5G_RSSI_CLOSE, " 5G RSSI close"}, + {NAN_TLV_TYPE_5G_RSSI_MIDDLE, " 5G RSSI middle"}, + {NAN_TLV_TYPE_5G_RSSI_CLOSE_PROXIMITY, + " 5G RSSI close proximity"}, + {NAN_TLV_TYPE_SID_BEACON, " SID beacon"}, + {NAN_TLV_TYPE_HOP_COUNT_LIMIT, " Hop count limit"}, + {NAN_TLV_TYPE_MASTER_PREFERENCE, " Master preference"}, + {NAN_TLV_TYPE_CLUSTER_ID_LOW, " Cluster ID low"}, + {NAN_TLV_TYPE_CLUSTER_ID_HIGH, " Cluster ID high"}, + {NAN_TLV_TYPE_RSSI_AVERAGING_WINDOW_SIZE, + " RSSI averaging window size"}, + {NAN_TLV_TYPE_CLUSTER_OUI_NETWORK_ID, + " Cluster OUI network ID"}, + {NAN_TLV_TYPE_SOURCE_MAC_ADDRESS, + " Source MAC address"}, + {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE_IN_SDF, + " Cluster attribute in SDF"}, + {NAN_TLV_TYPE_SOCIAL_CHANNEL_SCAN_PARAMS, + " Social channel scan params"}, + {NAN_TLV_TYPE_DEBUGGING_FLAGS, " Debugging flags"}, + {NAN_TLV_TYPE_POST_NAN_CONNECTIVITY_CAPABILITIES_TRANSMIT, + " Post nan connectivity capabilities transmit"}, + {NAN_TLV_TYPE_POST_NAN_DISCOVERY_ATTRIBUTE_TRANSMIT, + " Post nan discovery attribute transmit"}, + {NAN_TLV_TYPE_FURTHER_AVAILABILITY_MAP, + " Further availability map"}, + {NAN_TLV_TYPE_HOP_COUNT_FORCE, " Hop count force"}, + {NAN_TLV_TYPE_RANDOM_FACTOR_FORCE, + " Random factor force"}, + {NAN_TLV_TYPE_RANDOM_UPDATE_TIME, + " Random update time"}, + {NAN_TLV_TYPE_EARLY_WAKEUP, " Early wakeup"}, + {NAN_TLV_TYPE_PERIODIC_SCAN_INTERVAL, + " Periodic scan interval"}, + {NAN_TLV_TYPE_DW_INTERVAL, " DW interval"}, + {NAN_TLV_TYPE_DB_INTERVAL, " DB interval"}, + {NAN_TLV_TYPE_FURTHER_AVAILABILITY, + " Further availability"}, + {NAN_TLV_TYPE_24G_CHANNEL, " 2.4G channel"}, + {NAN_TLV_TYPE_5G_CHANNEL, " 5G channel"}, + {NAN_TLV_TYPE_CONFIG_LAST, " Config last"}, + + /* Attributes types */ + {NAN_TLV_TYPE_ATTRS_FIRST, " Attributes first"}, + {NAN_TLV_TYPE_AVAILABILITY_INTERVALS_MAP, + " Availability intervals map"}, + {NAN_TLV_TYPE_WLAN_MESH_ID, " WLAN mesh ID"}, + {NAN_TLV_TYPE_MAC_ADDRESS, " MAC address"}, + {NAN_TLV_TYPE_RECEIVED_RSSI_VALUE, + " Received RSSI value"}, + {NAN_TLV_TYPE_CLUSTER_ATTRIBUTE, + " Cluster attribute"}, + {NAN_TLV_TYPE_WLAN_INFRA_SSID, " WLAN infra SSID"}, + {NAN_TLV_TYPE_ATTRS_LAST, " Attributes last"}, + + /* Events Type */ + {NAN_TLV_TYPE_EVENTS_FIRST, " Events first"}, + {NAN_TLV_TYPE_EVENT_SELF_STATION_MAC_ADDRESS, + " Event Self station MAC address"}, + {NAN_TLV_TYPE_EVENT_STARTED_CLUSTER, + " Event started cluster"}, + {NAN_TLV_TYPE_EVENT_JOINED_CLUSTER, + " Event joined cluster"}, + {NAN_TLV_TYPE_EVENT_CLUSTER_SCAN_RESULTS, + " Event cluster scan results"}, + {NAN_TLV_TYPE_FAW_MEM_AVAIL, + " FAW memory availability"}, + {NAN_TLV_TYPE_EVENTS_LAST, " Events last"}, + + /* TCA types */ + {NAN_TLV_TYPE_TCA_FIRST, " TCA-Threshold Crossing Alert first"}, + {NAN_TLV_TYPE_CLUSTER_SIZE_REQ, + " Cluster size request"}, + {NAN_TLV_TYPE_CLUSTER_SIZE_RSP, + " Cluster size response"}, + {NAN_TLV_TYPE_TCA_LAST, " TCA last"}, + + /* Statistics types */ + {NAN_TLV_TYPE_STATS_FIRST, " Stats first"}, + {NAN_TLV_TYPE_DE_PUBLISH_STATS, + " Discovery engine publish stats"}, + {NAN_TLV_TYPE_DE_SUBSCRIBE_STATS, + " Discovery engine subscribe stats"}, + {NAN_TLV_TYPE_DE_MAC_STATS, + " Discovery engine MAC stats"}, + {NAN_TLV_TYPE_DE_TIMING_SYNC_STATS, + " Discovery engine timing sync stats"}, + {NAN_TLV_TYPE_DE_DW_STATS, + " Discovery engine DW stats"}, + {NAN_TLV_TYPE_DE_STATS, " Discovery engine stats"}, + {NAN_TLV_TYPE_STATS_LAST, " Stats last"}, + + {NAN_TLV_TYPE_LAST, " Last"} +}; + +struct errorCode { + NanStatusType frameworkError; + NanInternalStatusType firmwareError; + char nan_error[NAN_ERROR_STR_LEN]; +}; + +struct errorCode errorCodeTranslation[] = { + {NAN_STATUS_SUCCESS, NAN_I_STATUS_SUCCESS, + "NAN status success"}, + + {NAN_STATUS_INTERNAL_FAILURE, NAN_I_STATUS_DE_FAILURE, + "NAN Discovery engine failure"}, + + {NAN_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID, NAN_I_STATUS_INVALID_HANDLE, + "Invalid Publish/Subscribe ID"}, + + {NAN_STATUS_NO_RESOURCE_AVAILABLE, NAN_I_STATUS_NO_SPACE_AVAILABLE, + "No space available"}, + + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_PUBLISH_TYPE, + "Invalid Publish type, can be 0 or 1"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_TYPE, + "Invalid Tx type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_VERSION, + "Invalid internal message version"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_LEN, + "Invalid message length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MSG_ID, + "Invalid message ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_MATCH_ALGORITHM, + "Invalid matching algorithm, can be 0(match once), 1(match continuous) or 2(match never)"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_LEN, + "Invalid TLV length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_TYPE, + "Invalid TLV type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_TLV_TYPE, + "Missing TLV type"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TOTAL_TLVS_LEN, + "Invalid total TLV length"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TLV_VALUE, + "Invalid TLV value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_TX_PRIORITY, + "Invalid Tx priority"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_CONNECTION_MAP, + "Invalid connection map"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_THRESHOLD_CROSSING_ALERT_ID, + "Invalid TCA-Threshold Crossing Alert ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_STATS_ID, + "Invalid STATS ID"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NAN_I_STATUS_TX_FAIL, + "Tx Fail"}, + + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_CLOSE_VALUE, + "Invalid RSSI close value range is 20dbm to 60dbm"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RSSI_MIDDLE_VALUE, + "Invalid RSSI middle value range is 20dbm to 75dbm"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HOP_COUNT_LIMIT, + "Invalid hop count limit, max hop count limit is 5"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE, + "Invalid cluster ID value. Please set the cluster id high greater than the cluster id low"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BACKGROUND_SCAN_PERIOD, + "Invalid background scan period. The range is 10 to 30 milliseconds"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_SCAN_CHANNEL, + "Invalid scan channel. Only valid channels are the NAN social channels"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP, + "Invalid post nan connectivity bitmap"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_NUMCHAN_VALUE, + "Invalid further availability map number of channel value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_DURATION_VALUE, + "Invalid further availability map duration value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CLASS_VALUE, + "Invalid further availability map class value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_CHANNEL_VALUE, + "Invalid further availability map channel value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE, + "Invalid further availability map availability interval bitmap value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_FURTHER_AVAILABILITY_MAP_MAP_ID, + "Invalid further availability map map ID"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE, + "Invalid post nan discovery connection type value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE, + "Invalid post nan discovery device role value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE, + "Invalid post nan discovery duration value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE, + "Invalid post nan discovery bitmap value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_MISSING_FUTHER_AVAILABILITY_MAP, + "Missing further availability map"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_BAND_CONFIG_FLAGS, + "Invalid band configuration flags"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE, + "Invalid random factor update time value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_ONGOING_SCAN_PERIOD, + "Invalid ongoing scan period"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DW_INTERVAL_VALUE, + "Invalid DW interval value"}, + {NAN_STATUS_INVALID_PARAM, NAN_I_STATUS_INVALID_DB_INTERVAL_VALUE, + "Invalid DB interval value"}, + + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_TIMEOUT, + "Terminated Reason: Timeout"}, + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_USER_REQUEST, + "Terminated Reason: User Request"}, + {NAN_STATUS_SUCCESS, NAN_I_PUBLISH_SUBSCRIBE_TERMINATED_REASON_COUNT_REACHED, + "Terminated Reason: Count Reached"}, + + {NAN_STATUS_INVALID_REQUESTOR_INSTANCE_ID, NAN_I_STATUS_INVALID_REQUESTER_INSTANCE_ID, + "Invalid match handle"}, + {NAN_STATUS_NAN_NOT_ALLOWED, NAN_I_STATUS_NAN_NOT_ALLOWED, + "Nan not allowed"}, + {NAN_STATUS_NO_OTA_ACK, NAN_I_STATUS_NO_OTA_ACK, + "No OTA ack"}, + {NAN_STATUS_ALREADY_ENABLED, NAN_I_STATUS_NAN_ALREADY_ENABLED, + "NAN is Already enabled"}, + {NAN_STATUS_FOLLOWUP_QUEUE_FULL, NAN_I_STATUS_FOLLOWUP_QUEUE_FULL, + "Follow-up queue full"}, + + {NAN_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED, NDP_I_UNSUPPORTED_CONCURRENCY, + "Unsupported Concurrency"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_CREATE_FAILED, + "NAN data interface create failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_NAN_DATA_IFACE_DELETE_FAILED, + "NAN data interface delete failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_INITIATOR_REQUEST_FAILED, + "NAN data initiator request failed"}, + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_DATA_RESPONDER_REQUEST_FAILED, + "NAN data responder request failed"}, + + {NAN_STATUS_INVALID_NDP_ID, NDP_I_INVALID_NDP_INSTANCE_ID, + "Invalid NDP instance ID"}, + + {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_RESPONSE_CODE, + "Invalid response code"}, + {NAN_STATUS_INVALID_PARAM, NDP_I_INVALID_APP_INFO_LEN, + "Invalid app info length"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_REQUEST_FAILED, + "Management frame request failed"}, + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_RESPONSE_FAILED, + "Management frame response failed"}, + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_CONFIRM_FAILED, + "Management frame confirm failed"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_END_FAILED, + "NDP end failed"}, + + {NAN_STATUS_PROTOCOL_FAILURE, NDP_I_MGMT_FRAME_END_REQUEST_FAILED, + "Management frame end request failed"}, + + {NAN_STATUS_INTERNAL_FAILURE, NDP_I_VENDOR_SPECIFIC_ERROR, + "Vendor specific error"} +}; + +void NanCommand::NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd, + u32 valueRcvd, + void* pResponse, + bool is_ndp_rsp) +{ + int i = 0, j = 0; + u16 msg_id; /* Based on the message_id in the header determine the Indication type */ + NanResponseMsg *pRsp; + NanPublishTerminatedInd* pRspInd; + NanDisabledInd* pRspdInd; + char tlvInfo[NAN_ERROR_STR_LEN]; + tlvInfo[0] = '\0'; + + if ((is_ndp_rsp == true) || isNanResponse()) { + pRsp = (NanResponseMsg*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRsp->status = errorCodeTranslation[i].frameworkError; + strlcpy(pRsp->nan_error, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + if (NAN_I_STATUS_INVALID_TLV_TYPE == firmwareErrorRecvd) { + for (j = 0; j < (int)(sizeof(tlvToStr)/sizeof(verboseTlv)); j++) { + if (tlvToStr[j].tlvType == valueRcvd) { + strlcpy(tlvInfo, tlvToStr[i].strTlv, NAN_ERROR_STR_LEN); + break; + } + } + } + strlcat(pRsp->nan_error, tlvInfo, sizeof(pRsp->nan_error)); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRsp->status = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRsp->nan_error, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRsp->status, valueRcvd, pRsp->nan_error); + } else { + msg_id = getIndicationType(); + + switch(msg_id) { + case NAN_INDICATION_PUBLISH_TERMINATED: + case NAN_INDICATION_SUBSCRIBE_TERMINATED: + case NAN_INDICATION_SELF_TRANSMIT_FOLLOWUP: + pRspInd = (NanPublishTerminatedInd*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRspInd->reason = errorCodeTranslation[i].frameworkError; + strlcpy(pRspInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRspInd->reason = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRspInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspInd->reason, valueRcvd, pRspInd->nan_reason); + break; + case NAN_INDICATION_DISABLED: + pRspdInd = (NanDisabledInd*)pResponse; + for (i = 0; i < (int)(sizeof(errorCodeTranslation)/ sizeof(errorCode)); i++) { + if (errorCodeTranslation[i].firmwareError == firmwareErrorRecvd) { + pRspdInd->reason = errorCodeTranslation[i].frameworkError; + strlcpy(pRspdInd->nan_reason, errorCodeTranslation[i].nan_error, NAN_ERROR_STR_LEN); + break; + } + } + if (i == (int)(sizeof(errorCodeTranslation)/sizeof(errorCode))) { + pRspdInd->reason = NAN_STATUS_INTERNAL_FAILURE; + strlcpy(pRspdInd->nan_reason, "NAN Discovery engine failure", NAN_ERROR_STR_LEN); + } + ALOGD("%s: Status: %d Error Info[value %d]: %s", __FUNCTION__, pRspdInd->reason, valueRcvd, pRspdInd->nan_reason); + break; + } + } +} + +int NanCommand::getNanResponse(transaction_id *id, NanResponseMsg *pRsp) +{ + if (mNanVendorEvent == NULL || pRsp == NULL) { + ALOGE("NULL check failed"); + return WIFI_ERROR_INVALID_ARGS; + } + + NanMsgHeader *pHeader = (NanMsgHeader *)mNanVendorEvent; + + switch (pHeader->msgId) { + case NAN_MSG_ID_ERROR_RSP: + { + pNanErrorRspMsg pFwRsp = \ + (pNanErrorRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_ERROR; + break; + } + case NAN_MSG_ID_CONFIGURATION_RSP: + { + pNanConfigurationRspMsg pFwRsp = \ + (pNanConfigurationRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_CONFIG; + } + break; + case NAN_MSG_ID_PUBLISH_SERVICE_CANCEL_RSP: + { + pNanPublishServiceCancelRspMsg pFwRsp = \ + (pNanPublishServiceCancelRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_PUBLISH_CANCEL; + pRsp->body.publish_response.publish_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_PUBLISH_SERVICE_RSP: + { + pNanPublishServiceRspMsg pFwRsp = \ + (pNanPublishServiceRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_PUBLISH; + pRsp->body.publish_response.publish_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_SUBSCRIBE_SERVICE_RSP: + { + pNanSubscribeServiceRspMsg pFwRsp = \ + (pNanSubscribeServiceRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_SUBSCRIBE; + pRsp->body.subscribe_response.subscribe_id = \ + pFwRsp->fwHeader.handle; + } + break; + case NAN_MSG_ID_SUBSCRIBE_SERVICE_CANCEL_RSP: + { + pNanSubscribeServiceCancelRspMsg pFwRsp = \ + (pNanSubscribeServiceCancelRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_SUBSCRIBE_CANCEL; + pRsp->body.subscribe_response.subscribe_id = \ + pFwRsp->fwHeader.handle; + break; + } + case NAN_MSG_ID_TRANSMIT_FOLLOWUP_RSP: + { + pNanTransmitFollowupRspMsg pFwRsp = \ + (pNanTransmitFollowupRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_TRANSMIT_FOLLOWUP; + break; + } + case NAN_MSG_ID_STATS_RSP: + { + pNanStatsRspMsg pFwRsp = \ + (pNanStatsRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->statsRspParams.status, + pFwRsp->statsRspParams.value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_STATS; + pRsp->body.stats_response.stats_type = \ + (NanStatsType)pFwRsp->statsRspParams.statsType; + ALOGV("%s: stats_type:%d",__func__, + pRsp->body.stats_response.stats_type); + u8 *pInputTlv = pFwRsp->ptlv; + NanTlv outputTlv; + memset(&outputTlv, 0, sizeof(outputTlv)); + u16 readLen = 0; + int remainingLen = (mNanDataLen - \ + (sizeof(NanMsgHeader) + sizeof(NanStatsRspParams))); + if (remainingLen > 0) { + readLen = NANTLV_ReadTlv(pInputTlv, &outputTlv, remainingLen); + ALOGV("%s: Remaining Len:%d readLen:%d type:%d length:%d", + __func__, remainingLen, readLen, outputTlv.type, + outputTlv.length); + if (outputTlv.length <= \ + sizeof(pRsp->body.stats_response.data)) { + handleNanStatsResponse(pRsp->body.stats_response.stats_type, + (char *)outputTlv.value, + &pRsp->body.stats_response, + outputTlv.length); + } + } else + ALOGV("%s: No TLV's present",__func__); + break; + } + case NAN_MSG_ID_ENABLE_RSP: + { + pNanEnableRspMsg pFwRsp = \ + (pNanEnableRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_ENABLED; + break; + } + case NAN_MSG_ID_DISABLE_RSP: + { + pNanDisableRspMsg pFwRsp = \ + (pNanDisableRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false); + pRsp->response_type = NAN_RESPONSE_DISABLED; + break; + } + case NAN_MSG_ID_TCA_RSP: + { + pNanTcaRspMsg pFwRsp = \ + (pNanTcaRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_RESPONSE_TCA; + break; + } + case NAN_MSG_ID_BEACON_SDF_RSP: + { + pNanBeaconSdfPayloadRspMsg pFwRsp = \ + (pNanBeaconSdfPayloadRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, 0, pRsp, false); + pRsp->response_type = NAN_RESPONSE_BEACON_SDF_PAYLOAD; + break; + } + case NAN_MSG_ID_CAPABILITIES_RSP: + { + pNanCapabilitiesRspMsg pFwRsp = \ + (pNanCapabilitiesRspMsg)mNanVendorEvent; + *id = (transaction_id)pFwRsp->fwHeader.transactionId; + NanErrorTranslation((NanInternalStatusType)pFwRsp->status, pFwRsp->value, pRsp, false); + pRsp->response_type = NAN_GET_CAPABILITIES; + pRsp->body.nan_capabilities.max_concurrent_nan_clusters = \ + pFwRsp->max_concurrent_nan_clusters; + pRsp->body.nan_capabilities.max_publishes = \ + pFwRsp->max_publishes; + pRsp->body.nan_capabilities.max_subscribes = \ + pFwRsp->max_subscribes; + pRsp->body.nan_capabilities.max_service_name_len = \ + pFwRsp->max_service_name_len; + pRsp->body.nan_capabilities.max_match_filter_len = \ + pFwRsp->max_match_filter_len; + pRsp->body.nan_capabilities.max_total_match_filter_len = \ + pFwRsp->max_total_match_filter_len; + pRsp->body.nan_capabilities.max_service_specific_info_len = \ + pFwRsp->max_service_specific_info_len; + pRsp->body.nan_capabilities.max_vsa_data_len = \ + pFwRsp->max_vsa_data_len; + pRsp->body.nan_capabilities.max_mesh_data_len = \ + pFwRsp->max_mesh_data_len; + pRsp->body.nan_capabilities.max_ndi_interfaces = \ + pFwRsp->max_ndi_interfaces; + pRsp->body.nan_capabilities.max_ndp_sessions = \ + pFwRsp->max_ndp_sessions; + pRsp->body.nan_capabilities.max_app_info_len = \ + pFwRsp->max_app_info_len; + pRsp->body.nan_capabilities.max_queued_transmit_followup_msgs = \ + pFwRsp->max_queued_transmit_followup_msgs; + pRsp->body.nan_capabilities.ndp_supported_bands = \ + pFwRsp->ndp_supported_bands; + pRsp->body.nan_capabilities.cipher_suites_supported = \ + pFwRsp->cipher_suites_supported; + pRsp->body.nan_capabilities.max_scid_len = \ + pFwRsp->max_scid_len; + pRsp->body.nan_capabilities.is_ndp_security_supported = \ + pFwRsp->is_ndp_security_supported; + pRsp->body.nan_capabilities.max_sdea_service_specific_info_len = \ + pFwRsp->max_sdea_service_specific_info_len; + pRsp->body.nan_capabilities.max_subscribe_address = \ + pFwRsp->max_subscribe_address; + if (pFwRsp->max_publishes > NAN_DEF_PUB_SUB) { + mNanCommandInstance->mNanMaxPublishes = pFwRsp->max_publishes; + mNanCommandInstance->reallocSvcParams(NAN_ROLE_PUBLISHER); + } + if (pFwRsp->max_subscribes > NAN_DEF_PUB_SUB) { + mNanCommandInstance->mNanMaxSubscribes = pFwRsp->max_subscribes; + mNanCommandInstance->reallocSvcParams(NAN_ROLE_SUBSCRIBER); + } + + break; + } + default: + return -1; + } + return 0; +} + +int NanCommand::handleNanResponse() +{ + //parse the data and call + //the response callback handler with the populated + //NanResponseMsg + NanResponseMsg rsp_data; + int ret; + transaction_id id; + + ALOGV("handleNanResponse called %p", this); + memset(&rsp_data, 0, sizeof(rsp_data)); + //get the rsp_data + ret = getNanResponse(&id, &rsp_data); + + ALOGI("handleNanResponse ret:%d status:%u value:%s response_type:%u", + ret, rsp_data.status, rsp_data.nan_error, rsp_data.response_type); + if (ret == 0 && (rsp_data.response_type == NAN_RESPONSE_STATS) && + (mStaParam != NULL) && + (rsp_data.body.stats_response.stats_type == NAN_STATS_ID_DE_TIMING_SYNC)) { + /* + Fill the staParam with appropriate values and return from here. + No need to call NotifyResponse as the request is for getting the + STA response + */ + NanSyncStats *pSyncStats = &rsp_data.body.stats_response.data.sync_stats; + mStaParam->master_rank = pSyncStats->myRank; + mStaParam->master_pref = (pSyncStats->myRank & 0xFF00000000000000) >> 56; + mStaParam->random_factor = (pSyncStats->myRank & 0x00FF000000000000) >> 48; + mStaParam->hop_count = pSyncStats->currAmHopCount; + mStaParam->beacon_transmit_time = pSyncStats->currAmBTT; + mStaParam->ndp_channel_freq = pSyncStats->ndpChannelFreq; + + ALOGI("%s:0x%02x master_pref 0x%02x random_factor 0x%02x hop_count %u Channel", + __func__, mStaParam->master_pref, mStaParam->random_factor, + mStaParam->hop_count, mStaParam->ndp_channel_freq); + + return ret; + } + //Call the NotifyResponse Handler + if (ret == 0 && mHandler.NotifyResponse) { + (*mHandler.NotifyResponse)(id, &rsp_data); + } + return ret; +} + +void NanCommand::handleNanStatsResponse(NanStatsType stats_type, + char *rspBuf, + NanStatsResponse *pRsp, + u32 message_len) +{ + if (stats_type == NAN_STATS_ID_DE_PUBLISH) { + NanPublishStats publish_stats; + if (message_len != sizeof(NanPublishStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanPublishStats)); + return; + } + FwNanPublishStats *pPubStats = (FwNanPublishStats *)rspBuf; + + publish_stats.validPublishServiceReqMsgs = + pPubStats->validPublishServiceReqMsgs; + publish_stats.validPublishServiceRspMsgs = + pPubStats->validPublishServiceRspMsgs; + publish_stats.validPublishServiceCancelReqMsgs = + pPubStats->validPublishServiceCancelReqMsgs; + publish_stats.validPublishServiceCancelRspMsgs = + pPubStats->validPublishServiceCancelRspMsgs; + publish_stats.validPublishRepliedIndMsgs = + pPubStats->validPublishRepliedIndMsgs; + publish_stats.validPublishTerminatedIndMsgs = + pPubStats->validPublishTerminatedIndMsgs; + publish_stats.validActiveSubscribes = pPubStats->validActiveSubscribes; + publish_stats.validMatches = pPubStats->validMatches; + publish_stats.validFollowups = pPubStats->validFollowups; + publish_stats.invalidPublishServiceReqMsgs = + pPubStats->invalidPublishServiceReqMsgs; + publish_stats.invalidPublishServiceCancelReqMsgs = + pPubStats->invalidPublishServiceCancelReqMsgs; + publish_stats.invalidActiveSubscribes = + pPubStats->invalidActiveSubscribes; + publish_stats.invalidMatches = pPubStats->invalidMatches; + publish_stats.invalidFollowups = pPubStats->invalidFollowups; + publish_stats.publishCount = pPubStats->publishCount; + publish_stats.publishNewMatchCount = pPubStats->publishNewMatchCount; + publish_stats.pubsubGlobalNewMatchCount = + pPubStats->pubsubGlobalNewMatchCount; + memcpy(&pRsp->data.publish_stats, &publish_stats, sizeof(NanPublishStats)); + } else if (stats_type == NAN_STATS_ID_DE_SUBSCRIBE) { + NanSubscribeStats sub_stats; + if (message_len != sizeof(NanSubscribeStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanSubscribeStats)); + return; + } + FwNanSubscribeStats *pSubStats = (FwNanSubscribeStats *)rspBuf; + + sub_stats.validSubscribeServiceReqMsgs = + pSubStats->validSubscribeServiceReqMsgs; + sub_stats.validSubscribeServiceRspMsgs = + pSubStats->validSubscribeServiceRspMsgs; + sub_stats.validSubscribeServiceCancelReqMsgs = + pSubStats->validSubscribeServiceCancelReqMsgs; + sub_stats.validSubscribeServiceCancelRspMsgs = + pSubStats->validSubscribeServiceCancelRspMsgs; + sub_stats.validSubscribeTerminatedIndMsgs = + pSubStats->validSubscribeTerminatedIndMsgs; + sub_stats.validSubscribeMatchIndMsgs = + pSubStats->validSubscribeMatchIndMsgs; + sub_stats.validSubscribeUnmatchIndMsgs = + pSubStats->validSubscribeUnmatchIndMsgs; + sub_stats.validSolicitedPublishes = + pSubStats->validSolicitedPublishes; + sub_stats.validMatches = pSubStats->validMatches; + sub_stats.validFollowups = pSubStats->validFollowups; + sub_stats.invalidSubscribeServiceReqMsgs = + pSubStats->invalidSubscribeServiceReqMsgs; + sub_stats.invalidSubscribeServiceCancelReqMsgs = + pSubStats->invalidSubscribeServiceCancelReqMsgs; + sub_stats.invalidSubscribeFollowupReqMsgs = + pSubStats->invalidSubscribeFollowupReqMsgs; + sub_stats.invalidSolicitedPublishes = + pSubStats->invalidSolicitedPublishes; + sub_stats.invalidMatches = pSubStats->invalidMatches; + sub_stats.invalidFollowups = pSubStats->invalidFollowups; + sub_stats.subscribeCount = pSubStats->subscribeCount; + sub_stats.bloomFilterIndex = pSubStats->bloomFilterIndex; + sub_stats.subscribeNewMatchCount = pSubStats->subscribeNewMatchCount; + sub_stats.pubsubGlobalNewMatchCount = + pSubStats->pubsubGlobalNewMatchCount; + memcpy(&pRsp->data.subscribe_stats, &sub_stats, sizeof(NanSubscribeStats)); + } else if (stats_type == NAN_STATS_ID_DE_DW) { + NanDWStats dw_stats; + if (message_len != sizeof(NanDWStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanDWStats)); + return; + } + FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf; + + dw_stats.validFrames = pMacStats->validFrames; + dw_stats.validActionFrames = pMacStats->validActionFrames; + dw_stats.validBeaconFrames = pMacStats->validBeaconFrames; + dw_stats.ignoredActionFrames = pMacStats->ignoredActionFrames; + dw_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames; + dw_stats.invalidFrames = pMacStats->invalidFrames; + dw_stats.invalidActionFrames = pMacStats->invalidActionFrames; + dw_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames; + dw_stats.invalidMacHeaders = pMacStats->invalidMacHeaders; + dw_stats.invalidPafHeaders = pMacStats->invalidPafHeaders; + dw_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames; + dw_stats.earlyActionFrames = pMacStats->earlyActionFrames; + dw_stats.inDwActionFrames = pMacStats->inDwActionFrames; + dw_stats.lateActionFrames = pMacStats->lateActionFrames; + dw_stats.framesQueued = pMacStats->framesQueued; + dw_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates; + dw_stats.completeByTRSp = pMacStats->completeByTRSp; + dw_stats.completeByTp75DW = pMacStats->completeByTp75DW; + dw_stats.completeByTendDW = pMacStats->completeByTendDW; + dw_stats.lateActionFramesTx = pMacStats->lateActionFramesTx; + memcpy(&pRsp->data.dw_stats, &dw_stats, sizeof(NanDWStats)); + } else if (stats_type == NAN_STATS_ID_DE_MAC) { + NanMacStats mac_stats; + if (message_len != sizeof(NanMacStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanMacStats)); + return; + } + FwNanMacStats *pMacStats = (FwNanMacStats *)rspBuf; + + mac_stats.validFrames = pMacStats->validFrames; + mac_stats.validActionFrames = pMacStats->validActionFrames; + mac_stats.validBeaconFrames = pMacStats->validBeaconFrames; + mac_stats.ignoredActionFrames = pMacStats->ignoredActionFrames; + mac_stats.ignoredBeaconFrames = pMacStats->ignoredBeaconFrames; + mac_stats.invalidFrames = pMacStats->invalidFrames; + mac_stats.invalidActionFrames = pMacStats->invalidActionFrames; + mac_stats.invalidBeaconFrames = pMacStats->invalidBeaconFrames; + mac_stats.invalidMacHeaders = pMacStats->invalidMacHeaders; + mac_stats.invalidPafHeaders = pMacStats->invalidPafHeaders; + mac_stats.nonNanBeaconFrames = pMacStats->nonNanBeaconFrames; + mac_stats.earlyActionFrames = pMacStats->earlyActionFrames; + mac_stats.inDwActionFrames = pMacStats->inDwActionFrames; + mac_stats.lateActionFrames = pMacStats->lateActionFrames; + mac_stats.framesQueued = pMacStats->framesQueued; + mac_stats.totalTRSpUpdates = pMacStats->totalTRSpUpdates; + mac_stats.completeByTRSp = pMacStats->completeByTRSp; + mac_stats.completeByTp75DW = pMacStats->completeByTp75DW; + mac_stats.completeByTendDW = pMacStats->completeByTendDW; + mac_stats.lateActionFramesTx = pMacStats->lateActionFramesTx; + mac_stats.twIncreases = pMacStats->twIncreases; + mac_stats.twDecreases = pMacStats->twDecreases; + mac_stats.twChanges = pMacStats->twChanges; + mac_stats.twHighwater = pMacStats->twHighwater; + mac_stats.bloomFilterIndex = pMacStats->bloomFilterIndex; + memcpy(&pRsp->data.mac_stats, &mac_stats, sizeof(NanMacStats)); + } else if (stats_type == NAN_STATS_ID_DE_TIMING_SYNC) { + NanSyncStats sync_stats; + if (message_len != sizeof(NanSyncStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanSyncStats)); + return; + } + FwNanSyncStats *pSyncStats = (FwNanSyncStats *)rspBuf; + + sync_stats.currTsf = pSyncStats->currTsf; + sync_stats.myRank = pSyncStats->myRank; + sync_stats.currAmRank = pSyncStats->currAmRank; + sync_stats.lastAmRank = pSyncStats->lastAmRank; + sync_stats.currAmBTT = pSyncStats->currAmBTT; + sync_stats.lastAmBTT = pSyncStats->lastAmBTT; + sync_stats.currAmHopCount = pSyncStats->currAmHopCount; + sync_stats.currRole = pSyncStats->currRole; + sync_stats.currClusterId = pSyncStats->currClusterId; + + sync_stats.timeSpentInCurrRole = pSyncStats->timeSpentInCurrRole; + sync_stats.totalTimeSpentAsMaster = pSyncStats->totalTimeSpentAsMaster; + sync_stats.totalTimeSpentAsNonMasterSync = + pSyncStats->totalTimeSpentAsNonMasterSync; + sync_stats.totalTimeSpentAsNonMasterNonSync = + pSyncStats->totalTimeSpentAsNonMasterNonSync; + sync_stats.transitionsToAnchorMaster = + pSyncStats->transitionsToAnchorMaster; + sync_stats.transitionsToMaster = + pSyncStats->transitionsToMaster; + sync_stats.transitionsToNonMasterSync = + pSyncStats->transitionsToNonMasterSync; + sync_stats.transitionsToNonMasterNonSync = + pSyncStats->transitionsToNonMasterNonSync; + sync_stats.amrUpdateCount = pSyncStats->amrUpdateCount; + sync_stats.amrUpdateRankChangedCount = + pSyncStats->amrUpdateRankChangedCount; + sync_stats.amrUpdateBTTChangedCount = + pSyncStats->amrUpdateBTTChangedCount; + sync_stats.amrUpdateHcChangedCount = + pSyncStats->amrUpdateHcChangedCount; + sync_stats.amrUpdateNewDeviceCount = + pSyncStats->amrUpdateNewDeviceCount; + sync_stats.amrExpireCount = pSyncStats->amrExpireCount; + sync_stats.mergeCount = pSyncStats->mergeCount; + sync_stats.beaconsAboveHcLimit = pSyncStats->beaconsAboveHcLimit; + sync_stats.beaconsBelowRssiThresh = pSyncStats->beaconsBelowRssiThresh; + sync_stats.beaconsIgnoredNoSpace = pSyncStats->beaconsIgnoredNoSpace; + sync_stats.beaconsForOurCluster = pSyncStats->beaconsForOtherCluster; + sync_stats.beaconsForOtherCluster = pSyncStats->beaconsForOtherCluster; + sync_stats.beaconCancelRequests = pSyncStats->beaconCancelRequests; + sync_stats.beaconCancelFailures = pSyncStats->beaconCancelFailures; + sync_stats.beaconUpdateRequests = pSyncStats->beaconUpdateRequests; + sync_stats.beaconUpdateFailures = pSyncStats->beaconUpdateFailures; + sync_stats.syncBeaconTxAttempts = pSyncStats->syncBeaconTxAttempts; + sync_stats.syncBeaconTxFailures = pSyncStats->syncBeaconTxFailures; + sync_stats.discBeaconTxAttempts = pSyncStats->discBeaconTxAttempts; + sync_stats.discBeaconTxFailures = pSyncStats->discBeaconTxFailures; + sync_stats.amHopCountExpireCount = pSyncStats->amHopCountExpireCount; + sync_stats.ndpChannelFreq = pSyncStats->ndpChannelFreq; + sync_stats.ndpChannelFreq2 = pSyncStats->ndpChannelFreq2; + sync_stats.schedUpdateChannelFreq = pSyncStats->schedUpdateChannelFreq; + memcpy(&pRsp->data.sync_stats, &sync_stats, sizeof(NanSyncStats)); + } else if (stats_type == NAN_STATS_ID_DE) { + NanDeStats de_stats; + if (message_len != sizeof(NanDeStats)) { + ALOGE("%s: stats_type = %d invalid stats length = %u expected length = %zu\n", + __func__, stats_type, message_len, sizeof(NanDeStats)); + return; + } + FwNanDeStats *pDeStats = (FwNanDeStats *)rspBuf; + + de_stats.validErrorRspMsgs = pDeStats->validErrorRspMsgs; + de_stats.validTransmitFollowupReqMsgs = + pDeStats->validTransmitFollowupReqMsgs; + de_stats.validTransmitFollowupRspMsgs = + pDeStats->validTransmitFollowupRspMsgs; + de_stats.validFollowupIndMsgs = + pDeStats->validFollowupIndMsgs; + de_stats.validConfigurationReqMsgs = + pDeStats->validConfigurationReqMsgs; + de_stats.validConfigurationRspMsgs = + pDeStats->validConfigurationRspMsgs; + de_stats.validStatsReqMsgs = pDeStats->validStatsReqMsgs; + de_stats.validStatsRspMsgs = pDeStats->validStatsRspMsgs; + de_stats.validEnableReqMsgs = pDeStats->validEnableReqMsgs; + de_stats.validEnableRspMsgs = pDeStats->validEnableRspMsgs; + de_stats.validDisableReqMsgs = pDeStats->validDisableReqMsgs; + de_stats.validDisableRspMsgs = pDeStats->validDisableRspMsgs; + de_stats.validDisableIndMsgs = pDeStats->validDisableIndMsgs; + de_stats.validEventIndMsgs = pDeStats->validEventIndMsgs; + de_stats.validTcaReqMsgs = pDeStats->validTcaReqMsgs; + de_stats.validTcaRspMsgs = pDeStats->validTcaRspMsgs; + de_stats.validTcaIndMsgs = pDeStats->validTcaIndMsgs; + de_stats.invalidTransmitFollowupReqMsgs = + pDeStats->invalidTransmitFollowupReqMsgs; + de_stats.invalidConfigurationReqMsgs = + pDeStats->invalidConfigurationReqMsgs; + de_stats.invalidStatsReqMsgs = pDeStats->invalidStatsReqMsgs; + de_stats.invalidEnableReqMsgs = pDeStats->invalidEnableReqMsgs; + de_stats.invalidDisableReqMsgs = pDeStats->invalidDisableReqMsgs; + de_stats.invalidTcaReqMsgs = pDeStats->invalidTcaReqMsgs; + memcpy(&pRsp->data.de_stats, &de_stats, sizeof(NanDeStats)); + } else { + ALOGE("Unknown stats_type:%d\n", stats_type); + } +} + +int NanCommand::handleNdpResponse(NanResponseType ndpCmdType, + struct nlattr **tb_vendor) +{ + //parse the data and call + //the response callback handler with the populated + //NanResponseMsg + NanResponseMsg rsp_data; + transaction_id id; + + memset(&rsp_data, 0, sizeof(rsp_data)); + + if ((!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]) || + (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE])) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + id = nla_get_u16(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + ALOGD("%s: Transaction id : val %d", __FUNCTION__, id); + + NanErrorTranslation((NanInternalStatusType)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE]), + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE]), &rsp_data, true); + rsp_data.response_type = ndpCmdType; + + if (ndpCmdType == NAN_DP_INITIATOR_RESPONSE) + { + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_NDP not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + rsp_data.body.data_request_response.ndp_instance_id = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + } + //Call the NotifyResponse Handler + if (mHandler.NotifyResponse) { + (*mHandler.NotifyResponse)(id, &rsp_data); + } + return WIFI_SUCCESS; +} diff --git a/wcn6740/qcwcn/wifi_hal/nancommand.h b/wcn6740/qcwcn/wifi_hal/nancommand.h new file mode 100644 index 0000000..ac2a64b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nancommand.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#ifndef __WIFI_HAL_NAN_COMMAND_H__ +#define __WIFI_HAL_NAN_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" +#include "wifi_hal.h" +#include "nan_cert.h" + +/* + * NAN Salt is a concatenation of salt_version, CSID, Service ID, PeerMac + * resulting in a total length of 14 bytes + */ +#define NAN_SECURITY_SALT_SIZE 14 +/* In Service ID calculation SHA-256 hash size is of max. 64 bytes */ +#define NAN_SVC_HASH_SIZE 64 +/* Service ID is the first 48 bits of the SHA-256 hash of the Service Name */ +#define NAN_SVC_ID_SIZE 6 +/* Default Service name length is 21 bytes */ +#define NAN_DEF_SVC_NAME_LEN 21 +/* As per NAN spec, 4096 iterations to be used for PMK calculation */ +#define NAN_PMK_ITERATIONS 4096 +/* Keep NCS-SK-128 Cipher Suite as default i.e. HMAC-SHA-256 algorithm */ +#define NAN_DEFAULT_NCS_SK NAN_CIPHER_SUITE_SHARED_KEY_128_MASK +/* Currently by default max 6 Publishes/Subscribes are allowed */ +#define NAN_DEF_PUB_SUB 6 +/* + * First bit of discovery_indication_cfg in NanEnableRequest indicates + * disableDiscoveryAddressChangeIndication + */ +#define NAN_DISC_ADDR_IND_DISABLED 0x01 + +typedef struct PACKED +{ + u32 instance_id; + u16 subscriber_publisher_id; + u8 service_id[NAN_SVC_ID_SIZE]; +} NanStoreSvcParams; + +typedef enum +{ + NAN_ROLE_NONE, + NAN_ROLE_PUBLISHER, + NAN_ROLE_SUBSCRIBER +} NanRole; + +class NanCommand : public WifiVendorCommand +{ +private: + NanCallbackHandler mHandler; + char *mNanVendorEvent; + u32 mNanDataLen; + NanStaParameter *mStaParam; + u8 mNmiMac[NAN_MAC_ADDR_LEN]; + u32 mNanMaxPublishes; + u32 mNanMaxSubscribes; + NanStoreSvcParams *mStorePubParams; + NanStoreSvcParams *mStoreSubParams; + bool mNanDiscAddrIndDisabled; + + //Function to check the initial few bytes of data to + //determine whether NanResponse or NanEvent + int isNanResponse(); + //Function which unparses the data and calls the NotifyResponse + int handleNanResponse(); + //Function which will parse the mVendorData and gets + // the rsp_data appropriately. + int getNanResponse(transaction_id *id, NanResponseMsg *pRsp); + //Function which will return the Nan Indication type based on + //the initial few bytes of mVendorData + NanIndicationType getIndicationType(); + //Function which calls the necessaryIndication callback + //based on the indication type + int handleNanIndication(); + //Various Functions to get the appropriate indications + int getNanPublishReplied(NanPublishRepliedInd *event); + int getNanPublishTerminated(NanPublishTerminatedInd *event); + int getNanMatch(NanMatchInd *event); + int getNanMatchExpired(NanMatchExpiredInd *event); + int getNanSubscribeTerminated(NanSubscribeTerminatedInd *event); + int getNanFollowup(NanFollowupInd *event); + int getNanDiscEngEvent(NanDiscEngEventInd *event); + int getNanDisabled(NanDisabledInd *event); + int getNanTca(NanTCAInd *event); + int getNanBeaconSdfPayload(NanBeaconSdfPayloadInd *event); + //Internal cleanup function + void cleanup(); + + static NanCommand *mNanCommandInstance; + + // Other private helper functions + int calcNanTransmitPostDiscoverySize( + const NanTransmitPostDiscovery *pPostDiscovery); + void fillNanSocialChannelParamVal( + const NanSocialChannelScanParams *pScanParams, + u32* pChannelParamArr); + u32 getNanTransmitPostConnectivityCapabilityVal( + const NanTransmitPostConnectivityCapability *pCapab); + void fillNanTransmitPostDiscoveryVal( + const NanTransmitPostDiscovery *pTxDisc, + u8 *pOutValue); + int calcNanFurtherAvailabilityMapSize( + const NanFurtherAvailabilityMap *pFam); + void fillNanFurtherAvailabilityMapVal( + const NanFurtherAvailabilityMap *pFam, + u8 *pOutValue); + + void getNanReceivePostConnectivityCapabilityVal( + const u8* pInValue, + NanReceivePostConnectivityCapability *pRxCapab); + void getNanReceiveSdeaCtrlParams(const u8* pInValue, + NanSdeaCtrlParams *pPeerSdeaParams); + int getNanReceivePostDiscoveryVal(const u8 *pInValue, + u32 length, + NanReceivePostDiscovery *pRxDisc); + int getNanFurtherAvailabilityMap(const u8 *pInValue, + u32 length, + u8* num_chans, + NanFurtherAvailabilityChannel *pFac); + void handleNanStatsResponse(NanStatsType stats_type, + char* rspBuf, + NanStatsResponse *pRsp, + u32 message_len); + + //Function which unparses the data and calls the NotifyResponse + int handleNdpResponse(NanResponseType ndpCmdtyp, struct nlattr **tb_vendor); + int handleNdpIndication(u32 ndpCmdType, struct nlattr **tb_vendor); + int getNdpRequest(struct nlattr **tb_vendor, NanDataPathRequestInd *event); + int getNdpConfirm(struct nlattr **tb_vendor, NanDataPathConfirmInd *event); + int getNdpEnd(struct nlattr **tb_vendor, NanDataPathEndInd *event); + int getNanTransmitFollowupInd(NanTransmitFollowupInd *event); + int getNanRangeRequestReceivedInd(NanRangeRequestInd *event); + int getNanRangeReportInd(NanRangeReportInd *event); + int getNdpScheduleUpdate(struct nlattr **tb_vendor, NanDataPathScheduleUpdateInd *event); +public: + NanCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + static NanCommand* instance(wifi_handle handle); + virtual ~NanCommand(); + + // This function implements creation of NAN specific Request + // based on the request type + virtual wifi_error create(); + virtual wifi_error requestEvent(); + virtual int handleResponse(WifiEvent &reply); + virtual int handleEvent(WifiEvent &event); + wifi_error setCallbackHandler(NanCallbackHandler nHandler); + + + //Functions to fill the vendor data appropriately + wifi_error putNanEnable(transaction_id id, const NanEnableRequest *pReq); + wifi_error putNanDisable(transaction_id id); + wifi_error putNanPublish(transaction_id id, const NanPublishRequest *pReq); + wifi_error putNanPublishCancel(transaction_id id, const NanPublishCancelRequest *pReq); + wifi_error putNanSubscribe(transaction_id id, const NanSubscribeRequest *pReq); + wifi_error putNanSubscribeCancel(transaction_id id, const NanSubscribeCancelRequest *pReq); + wifi_error putNanTransmitFollowup(transaction_id id, const NanTransmitFollowupRequest *pReq); + wifi_error putNanStats(transaction_id id, const NanStatsRequest *pReq); + wifi_error putNanConfig(transaction_id id, const NanConfigRequest *pReq); + wifi_error putNanTCA(transaction_id id, const NanTCARequest *pReq); + wifi_error putNanBeaconSdfPayload(transaction_id id, const NanBeaconSdfPayloadRequest *pReq); + wifi_error getNanStaParameter(wifi_interface_handle iface, NanStaParameter *pRsp); + wifi_error putNanCapabilities(transaction_id id); + wifi_error putNanDebugCommand(NanDebugParams debug, int debug_msg_length); + + /* Functions for NAN error translation + For NanResponse, NanPublishTerminatedInd, NanSubscribeTerminatedInd, + NanDisabledInd, NanTransmitFollowupInd: + function to translate firmware specific errors + to generic freamework error along with the error string + */ + void NanErrorTranslation(NanInternalStatusType firmwareErrorRecvd, + u32 valueRcvd, + void *pRsp, + bool is_ndp_rsp); + + /* Functions for NAN passphrase to PMK calculation */ + void saveNmi(u8 *mac); + u8 *getNmi(); + void saveServiceId(u8 *service_id, u16 sub_pub_handle, + u32 instance_id, NanRole Pool); + u8 *getServiceId(u32 instance_id, NanRole Pool); + void deleteServiceId(u16 sub_handle, u32 instance_id, NanRole pool); + void allocSvcParams(); + void reallocSvcParams(NanRole pool); + void deallocSvcParams(); +}; +#endif /* __WIFI_HAL_NAN_COMMAND_H__ */ + diff --git a/wcn6740/qcwcn/wifi_hal/nud_stats.h b/wcn6740/qcwcn/wifi_hal/nud_stats.h new file mode 100644 index 0000000..c88b3a9 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/nud_stats.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017-2018, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include <stdint.h> +#include <fcntl.h> +#include <inttypes.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include "wifi_hal.h" +#include <bits/in_addr.h> + +#define INET6_ADDRSTRLEN 46 + +extern "C" { + const char* inet_ntop(int __af, const void* __src, char* __dst, socklen_t __size); +} + +typedef struct { + uint16_t arp_req_count_from_netdev; + uint16_t arp_req_count_to_lower_mac; + uint16_t arp_req_rx_count_by_lower_mac; + uint16_t arp_req_count_tx_success; + uint16_t arp_rsp_rx_count_by_lower_mac; + uint16_t arp_rsp_rx_count_by_upper_mac; + uint16_t arp_rsp_count_to_netdev; + uint16_t arp_rsp_count_out_of_order_drop; + uint8_t ap_link_active; + uint8_t is_duplicate_addr_detection; +} nud_stats; + +typedef struct { + uint16_t pkt_req_count_from_netdev; + uint16_t pkt_req_count_to_lower_mac; + uint16_t pkt_req_rx_count_by_lower_mac; + uint16_t pkt_req_count_tx_success; + uint16_t pkt_rsp_rx_count_by_lower_mac; + uint16_t pkt_rsp_rx_count_by_upper_mac; + uint16_t pkt_rsp_count_to_netdev; + uint16_t pkt_rsp_count_out_of_order_drop; +} pkt_stats; + +typedef struct{ + u32 pkt_Type; + char* domain_name; + u32 src_port; + u32 dst_port; + struct in_addr ipv4_addr; + u8 ipv6_addr[16]; + pkt_stats stats; +} cmdData; + +/* callback for get NUD stats */ +typedef struct { + void (*on_pkt_stats_results) (nud_stats *stats, + int mnumStats, cmdData *pkt_stats); +} pkt_stats_result_handler; + +wifi_error wifi_set_nud_stats(wifi_interface_handle iface, u32 gw_addr, + cmdData set_data); +wifi_error wifi_get_nud_stats(wifi_interface_handle iface, + pkt_stats_result_handler handler); +wifi_error wifi_clear_nud_stats(wifi_interface_handle iface, + cmdData set_data); diff --git a/wcn6740/qcwcn/wifi_hal/pkt_stats.h b/wcn6740/qcwcn/wifi_hal/pkt_stats.h new file mode 100644 index 0000000..e01da3b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/pkt_stats.h @@ -0,0 +1,674 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef _PKT_STATS_H_ +#define _PKT_STATS_H_ + +/* Types of packet log events. + * Tx stats will be sent from driver with the help of multiple events. + * Need to parse the events PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT + * as of now for the required stats. Rest of the events can ignored. + */ +#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 +/* Rx stats will be sent from driver with event ID- PKTLOG_TYPE_RX_STAT */ +#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_PKT_STATS 9 +#define PKTLOG_TYPE_PKT_DUMP 10 +#define PKTLOG_TYPE_PKT_DUMP_V2 11 +#define PKTLOG_TYPE_MAX 12 +#define BW_OFFSET 8 +#define INVALID_RSSI 255 +#define INVALID_RATE_CODE 0xff + +/* Based on pkt log V2, this type of event will triggered */ +#define PKTLOG_TYPE_PKT_SW_EVENT 10 +#define PKTLOG_TYPE_RX_STATBUF 22 //Full Rx pktlog stats +#define PKTLOG_TYPE_LITE_T2H 23 //PPDU Level Tx pktlog stats +#define PKTLOG_TYPE_LITE_RX 24 //PPDU Level Rx pktlog stats + + +#define PKT_INFO_FLG_TX_LOCAL_S 0x1 +#define PKT_INFO_FLG_RX_HOST_RXD 0x2 +#define PKT_INFO_FLG_TX_REMOTE_S 0x4 +#define PKT_INFO_FLG_RX_LOCAL_S 0x8 +#define PKT_INFO_FLG_RX_REMOTE_S 0x10 +#define PKT_INFO_FLG_RX_LOCAL_DISCARD_S 0x20 +#define PKT_INFO_FLG_RX_REMOTE_DISCARD_S 0x40 +#define PKT_INFO_FLG_RX_REORDER_STORE_S 0x80 +#define PKT_INFO_FLG_RX_REORDER_DROP_S 0x100 +#define PKT_INFO_FLG_RX_PEER_INFO_S 0x200 +#define PKT_INFO_FLG_UNKNOWN_S 0x400 +#define PKT_INFO_FLG_PKT_DUMP_V2 0x8000 + +/* Depend on packet log version V2 this + * offset are define, for more info need to + * check from firmware side. + */ +#define TX_SUCCESS_TMS_OFFSET 56 +#define LINK_LAYER_TX_SQN_OFFSET 66 +#define RATE_CODE_OFFSET 68 +#define TX_STATUS_OFFSET 70 +#define TX_RSSI_OFFSET 71 +#define NO_RETRIES_OFFSET 75 +#define EXT_FLAGS_OFFSET 76 +#define BMAP_FAILED_OFFSET 84 +#define BMAP_ENQUEUED_OFFSET 92 +#define FRAME_CTRL_OFFSET 216 +#define QOS_CTRL_OFFSET 218 + +/* MAX HT/VHT mcs index */ +#define MAX_VHT_MCS_IDX 10 +#define MAX_HT_MCS_IDX 8 + +/* MAX CCK/OFDM rate index */ +#define MAX_CCK_MCS_IDX 4 +#define MAX_OFDM_MCS_IDX 8 + +/* MASK value of flags based on RX_STAT content. + * These are the events that carry Rx decriptor + */ +#define PKT_INFO_FLG_RX_RXDESC_MASK \ + (PKT_INFO_FLG_RX_HOST_RXD | \ + PKT_INFO_FLG_RX_LOCAL_S | \ + PKT_INFO_FLG_RX_REMOTE_S | \ + PKT_INFO_FLG_RX_LOCAL_DISCARD_S | \ + PKT_INFO_FLG_RX_REMOTE_DISCARD_S) + +/* Format of the packet stats event*/ +typedef struct { + u16 flags; + u16 missed_cnt; + u16 log_type; + u16 size; + u32 timestamp; +} __attribute__((packed)) wh_pktlog_hdr_t; + +/* Format of the v2 packet stats event*/ +typedef struct { + u16 flags; + u16 missed_cnt; + u16 log_type : 8; //[7:0] + u16 mac_id : 8; //[15:8] + u16 size; + u32 timestamp; + u32 reserved; +} __attribute__((packed)) wh_pktlog_hdr_v2_t; + +/*Rx stats specific structures. */ +struct rx_attention { + u32 first_mpdu : 1; //[0] + u32 last_mpdu : 1; //[1] + u32 reserved1 : 6; //[7:2] + u32 mgmt_type : 1; //[8] + u32 ctrl_type : 1; //[9] + u32 reserved2 : 6; //[15:10] + u32 overflow_err : 1; //[16] + u32 msdu_length_err : 1; //[17] + u32 tcp_udp_chksum_fail : 1; //[18] + u32 ip_chksum_fail : 1; //[19] + u32 reserved3 : 7; //[26:20] + u32 mpdu_length_err : 1; //[27] + u32 tkip_mic_err : 1; //[28] + u32 decrypt_err : 1; //[29] + u32 fcs_err : 1; //[30] + u32 msdu_done : 1; //[31] +} __attribute__((packed)); + +struct rx_mpdu_start { + u32 reserved1 : 13; //[12:0] + u32 encrypted : 1; //[13] + u32 retry : 1; //[14] + u32 reserved2 : 1; //[15] + u32 seq_num : 12; //[27:16] + u32 reserved3 : 4; //[31:28] + u32 reserved4; + u32 reserved5 : 28; //[27:0] + u32 tid : 4; //[31:28] +} __attribute__((packed)); + +/*Indicates the decap-format of the packet*/ +enum { + RAW=0, // RAW: No decapsulation + NATIVEWIFI, + ETHERNET2, // (DIX) + ETHERNET // (SNAP/LLC) +}; + +struct rx_msdu_start { + u32 reserved1[2]; + u32 reserved2 : 8; //[7:0] + u32 decap_format : 2; //[9:8] + u32 reserved3 : 22; //[31:10] +} __attribute__((packed)); + +struct rx_msdu_end { + u32 reserved1[4]; + u32 reserved2 : 15; + u32 last_msdu : 1; //[15] + u32 reserved3 : 16; //[31:16] +} __attribute__((packed)); + +struct rx_mpdu_end { + u32 reserved1 : 13; //[12:0] + u32 overflow_err : 1; //[13] + u32 last_mpdu : 1; //[14] + u32 post_delim_err : 1; //[15] + u32 reserved2 : 12; //[27:16] + u32 mpdu_length_err : 1; //[28] + u32 tkip_mic_err : 1; //[29] + u32 decrypt_err : 1; //[30] + u32 fcs_err : 1; //[31] +} __attribute__((packed)); + +/* structure implemented w.r.t PKT_LOG_V2 Version */ +struct rx_msdu_start_v1 { + u32 reserved1[2]; + u32 reserved2 : 8; //[7:0] + u32 decap_format : 2; //[9:8] + u32 reserved3 : 22; //[31:10] + u32 reserved4[2]; +} __attribute__((packed)); + +struct rx_msdu_end_v1 { + u32 reserved1[4]; + u32 reserved2 : 15; //[14:0] + u32 last_msdu : 1; //[15] + u32 reserved3 : 16; //[31:16] + u32 reserved4[9]; +} __attribute__((packed)); +/************************************************************/ + +#define PREAMBLE_L_SIG_RATE 0x04 +#define PREAMBLE_VHT_SIG_A_1 0x08 +#define PREAMBLE_VHT_SIG_A_2 0x0c + +/* Wifi Logger preamble */ +#define WL_PREAMBLE_CCK 0 +#define WL_PREAMBLE_OFDM 1 +#define WL_PREAMBLE_HT 2 +#define WL_PREAMBLE_VHT 3 + +#define BITMASK(x) ((1<<(x)) - 1 ) +#define MAX_BA_WINDOW_SIZE 64 +#define SEQ_NUM_RANGE 4096 +#define BITMAP_VAR_SIZE 32 + +/* Contains MCS related stats */ +struct rx_ppdu_start { + u32 reserved1[4]; + u32 rssi_comb : 8; //[7:0] + u32 reserved2 : 24; //[31:8] + u32 l_sig_rate : 4; //[3:0] + u32 l_sig_rate_select : 1; //[4] + u32 reserved3 : 19; //[23:5] + u32 preamble_type : 8; //[31:24] + u32 ht_sig_vht_sig_a_1 : 24; //[23:0] + u32 reserved4 : 8; //[31:24] + u32 ht_sig_vht_sig_a_2 : 24; //[23:0] + u32 reserved5 : 8; //[31:25] + u32 reserved6[2]; +} __attribute__((packed)); + +struct rx_ppdu_end { + u32 reserved1[16]; + u32 tsf_timestamp; + u32 reserved2[5]; +} __attribute__((packed)); + +struct rx_ppdu_end_V1 { + u32 reserved1[18]; + u32 wb_timestamp_lower_32; + u32 reserved2[18]; +} __attribute__((packed)); + +#define MAX_MSDUS_PER_MPDU 3 +#define MAX_RXMPDUS_PER_AMPDU 64 +#define RX_HTT_HDR_STATUS_LEN 64 +/* RX Data length is 256 for PKT_LOG_V2 Version */ +#define RX_HTT_HDR_STATUS_LEN_V1 256 + +typedef struct { + struct rx_attention attention; + u32 reserved1; + 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]; +}__attribute__((packed)) rb_pkt_stats_t; + +/* structure implemented w.r.t PKT_LOG_V2 Version */ +typedef struct { + struct rx_attention attention; + u32 reserved1[2]; + struct rx_mpdu_start mpdu_start; + struct rx_msdu_start_v1 msdu_start; + struct rx_msdu_end_v1 msdu_end; + struct rx_mpdu_end mpdu_end; + struct rx_ppdu_start ppdu_start; + struct rx_ppdu_end_V1 ppdu_end; + char rx_hdr_status[RX_HTT_HDR_STATUS_LEN_V1]; +}__attribute__((packed)) rb_pkt_stats_t_v1; +/************************************************************/ + +/*Tx stats specific structures. */ +struct ppdu_status { + u32 ba_start_seq_num : 12; //[11:0] + u32 reserved1 : 3; //[14:12] + u32 ba_status : 1; //[15] + u32 reserved2 : 15; //[30:16] + u32 tx_ok : 1; //[31] + u32 ba_bitmap_31_0 : 32; //[31:0] + u32 ba_bitmap_63_32 : 32; //[31:0] + u32 reserved3[8]; + u32 ack_rssi_ave : 8; //[7:0] + u32 reserved4 : 16; //[23:8] + u32 total_tries : 5; //[28:24] + u32 reserved5 : 3; //[31:29] + u32 reserved6[4]; +} __attribute__((packed)); + +/*Contains tx timestamp*/ +struct try_status { + u32 timestamp : 23; //[22:0] + u32 reserved1 : 1; //[23] + u32 series : 1; //[24] + u32 reserved2 : 3; //[27:25] + u32 packet_bw : 2; //[29:28] + u32 reserved3 : 1; //[30] + u32 tx_packet : 1; //[31] +} __attribute__((packed)); + +struct try_list { + struct try_status try_st[16]; +} __attribute__((packed)); + + +struct tx_ppdu_end { + struct try_list try_list; + struct ppdu_status stat; +} __attribute__((packed)); + +/*Tx MCS and data rate ralated stats */ +struct series_bw { + u32 reserved1 : 28; //[27:0] + u32 short_gi : 1; //[28] + u32 reserved2 : 3; //[31:29] + u32 reserved3 : 24; //[23:21] + u32 rate : 4; //[27:24] + u32 nss : 2; //[29:28] + u32 preamble_type : 2; //[31:30] + u32 reserved4[2]; +} __attribute__((packed)); + +enum tx_bw { + BW_20_MHZ, + BW_40_MHZ, + BW_80_MHZ, + BW_160_MHZ +}; + +#define DATA_PROTECTED 14 +struct tx_ppdu_start { + u32 reserved1[2]; + u32 start_seq_num : 12; //[11:0] + u32 reserved2 : 20; //[31:12] + u32 seqnum_bitmap_31_0 : 32; //[31:0] + u32 seqnum_bitmap_63_32 : 32; //[31:0] + u32 reserved3[8]; + u32 reserved4 : 15; //[14:0] + u32 ampdu : 1; //[15] + u32 no_ack : 1; //[16] + u32 reserved5 : 15; //[31:17] + u32 reserved6 : 16; //[15:0] + u32 frame_control : 16; //[31:16] + u32 reserved7 : 16; //[23:21] + u32 qos_ctl : 16; //[31:16] + u32 reserved8[4]; + u32 reserved9 : 24; //[23:21] + u32 valid_s0_bw20 : 1; //[24] + u32 valid_s0_bw40 : 1; //[25] + u32 valid_s0_bw80 : 1; //[26] + u32 valid_s0_bw160 : 1; //[27] + u32 valid_s1_bw20 : 1; //[28] + u32 valid_s1_bw40 : 1; //[29] + u32 valid_s1_bw80 : 1; //[30] + u32 valid_s1_bw160 : 1; //[31] + struct series_bw s0_bw20; + struct series_bw s0_bw40; + struct series_bw s0_bw80; + struct series_bw s0_bw160; + struct series_bw s1_bw20; + struct series_bw s1_bw40; + struct series_bw s1_bw80; + struct series_bw s1_bw160; + u32 reserved10[3]; +} __attribute__((packed)); + +#define PKTLOG_MAX_TXCTL_WORDS 57 /* +2 words for bitmap */ +typedef struct { + u32 reserved1[3]; + union { + u32 txdesc_ctl[PKTLOG_MAX_TXCTL_WORDS]; + struct tx_ppdu_start ppdu_start; + }u; +} __attribute__((packed)) wh_pktlog_txctl; + +/* Required stats are spread across multiple + * events(PKTLOG_TYPE_TX_CTRL and PKTLOG_TYPE_TX_STAT here). + * Need to aggregate the stats collected in each event and write to the + * ring buffer only after receiving all the expected stats. + * Need to preserve the stats in hal_info till then and use tx_stats_events + * flag to track the events. + * prev_seq_no: Can used to track the events that come from driver and identify + * if any event is missed. + */ + +/* PKT_LOG_V2 Base strcuture used to parse buffer */ +typedef struct { + u16 frm_ctrl; + u8 tx_ok; + u16 qos_ctrl; + u64 bmap_failed; + u64 bmap_enqueued; +} __attribute__((packed)) node_pkt_stats; + +typedef u8 A_RATECODE; + +/* Rate Code as per PKT_LOG_V2 Version */ +typedef struct { + A_RATECODE rateCode; + u8 flags; +} RATE_CODE; + +/* bandwidht type*/ +typedef enum { + BW_20MHZ, + BW_40MHZ, + BW_80MHZ, + BW_160MHZ, +} bandwidth; + +/* Preamble type*/ +typedef enum { + WIFI_HW_RATECODE_PREAM_OFDM = 0, + WIFI_HW_RATECODE_PREAM_CCK = 1, + WIFI_HW_RATECODE_PREAM_HT = 2, + WIFI_HW_RATECODE_PREAM_VHT = 3, + WIFI_HW_RATECODE_PREAM_COUNT, +} WIFI_HW_RATECODE_PREAM_TYPE; + +/** + * struct index_data_rate_type - non vht data rate type + * @rate_index: cck rate index + * @cck_rate: CCK supported rate table + */ +struct index_data_rate_cck_type { + uint8_t rate_index; + uint16_t cck_rate[2]; +}; + +/** + * struct index_data_rate_type - non vht data rate type + * @rate_index: ofdm rate index + * @ofdm__rate: OFDM supported rate table + */ +struct index_data_rate_ofdm_type { + uint8_t rate_index; + uint16_t ofdm_rate[2]; +}; + +/*Below CCK/OFDM table refer from firmware Arch */ +/* Rate Table Based on CCK */ +static struct index_data_rate_cck_type cck_mcs_nss1[] = { + /*RC LKbps SKbps */ + {0x40, {11000, 11000} }, + {0x41, {5500, 5500} }, + {0x42, {2000, 2000} }, + {0x43, {1000, 1000} } +}; + +/* Rate Table Based on OFDM */ +static struct index_data_rate_ofdm_type ofdm_mcs_nss1[] = { + /*RC LKbps SKbps */ + {0x00, {48000, 48000} }, + {0x01, {34000, 24000} }, + {0x02, {12000, 12000} }, + {0x03, {6000, 6000} }, + {0x04, {54000, 54000} }, + {0x05, {36000, 36000} }, + {0x06, {18000, 18000} }, + {0x07, {9000, 9000} } +}; + +/** + * struct index_data_rate_type - non vht data rate type + * @mcs_index: mcs rate index + * @ht20_rate: HT20 supported rate table + * @ht40_rate: HT40 supported rate table + */ +struct index_data_rate_type { + uint8_t mcs_index; + uint16_t ht20_rate[2]; + uint16_t ht40_rate[2]; +}; + +/** + * struct index_vht_data_rate_type - vht data rate type + * @mcs_index: mcs rate index + * @ht20_rate: VHT20 supported rate table + * @ht40_rate: VHT40 supported rate table + * @ht80_rate: VHT80 supported rate table + */ +struct index_vht_data_rate_type { + uint8_t mcs_index; + uint16_t ht20_rate[2]; + uint16_t ht40_rate[2]; + uint16_t ht80_rate[2]; +}; + +/*Below HT/VHT table refer from Host Driver + * MCS Based rate table + * HT MCS parameters with Nss = 1 + */ +static struct index_data_rate_type mcs_nss1[] = { + /* MCS L20 S20 L40 S40 */ + {0, {65, 72}, {135, 150 } }, + {1, {130, 144}, {270, 300 } }, + {2, {195, 217}, {405, 450 } }, + {3, {260, 289}, {540, 600 } }, + {4, {390, 433}, {815, 900 } }, + {5, {520, 578}, {1080, 1200} }, + {6, {585, 650}, {1215, 1350} }, + {7, {650, 722}, {1350, 1500} } +}; + +/* HT MCS parameters with Nss = 2 */ +static struct index_data_rate_type mcs_nss2[] = { + /* MCS L20 S20 L40 S40 */ + {0, {130, 144}, {270, 300 } }, + {1, {260, 289}, {540, 600 } }, + {2, {390, 433}, {810, 900 } }, + {3, {520, 578}, {1080, 1200} }, + {4, {780, 867}, {1620, 1800} }, + {5, {1040, 1156}, {2160, 2400} }, + {6, {1170, 1300}, {2430, 2700} }, + {7, {1300, 1440}, {2700, 3000} } +}; + +/* MCS Based VHT rate table + * MCS parameters with Nss = 1 + */ +static struct index_vht_data_rate_type vht_mcs_nss1[] = { + /* MCS L20 S20 L40 S40 L80 S80 */ + {0, {65, 72 }, {135, 150}, {293, 325} }, + {1, {130, 144}, {270, 300}, {585, 650} }, + {2, {195, 217}, {405, 450}, {878, 975} }, + {3, {260, 289}, {540, 600}, {1170, 1300} }, + {4, {390, 433}, {810, 900}, {1755, 1950} }, + {5, {520, 578}, {1080, 1200}, {2340, 2600} }, + {6, {585, 650}, {1215, 1350}, {2633, 2925} }, + {7, {650, 722}, {1350, 1500}, {2925, 3250} }, + {8, {780, 867}, {1620, 1800}, {3510, 3900} }, + {9, {865, 960}, {1800, 2000}, {3900, 4333} } +}; + +/*MCS parameters with Nss = 2*/ +static struct index_vht_data_rate_type vht_mcs_nss2[] = { + /* MCS L20 S20 L40 S40 L80 S80 */ + {0, {130, 144}, {270, 300}, { 585, 650} }, + {1, {260, 289}, {540, 600}, {1170, 1300} }, + {2, {390, 433}, {810, 900}, {1755, 1950} }, + {3, {520, 578}, {1080, 1200}, {2340, 2600} }, + {4, {780, 867}, {1620, 1800}, {3510, 3900} }, + {5, {1040, 1156}, {2160, 2400}, {4680, 5200} }, + {6, {1170, 1300}, {2430, 2700}, {5265, 5850} }, + {7, {1300, 1444}, {2700, 3000}, {5850, 6500} }, + {8, {1560, 1733}, {3240, 3600}, {7020, 7800} }, + {9, {1730, 1920}, {3600, 4000}, {7800, 8667} } +}; +/*********************************************************/ + +#define RING_BUF_ENTRY_SIZE 512 +#define PKT_STATS_BUF_SIZE 128 +struct pkt_stats_s { + u8 tx_stats_events; + /* TODO: Need to handle the case if size of the stats are more + * than 512 bytes. Currently, the tx size is 34 bytes and ring buffer entry + * size is 12 bytes. + */ + u8 tx_stats[PKT_STATS_BUF_SIZE]; + u8 num_msdu; + u16 start_seq_num; + u16 ba_seq_num; + u32 ba_bitmap_31_0; + u32 ba_bitmap_63_32; + u32 tx_seqnum_bitmap_31_0; + u32 tx_seqnum_bitmap_63_32; + u32 shifted_bitmap_31_0; + u32 shifted_bitmap_63_32; + bool isBlockAck; + u8 tx_bandwidth; + u8 series; +}; + +typedef union { + struct { + u16 rate : 4; + u16 nss : 2; + u16 preamble : 2; + u16 bw : 2; + u16 short_gi : 1; + u16 reserved : 5; + } mcs_s; + u16 mcs; +} MCS; + +typedef struct { + MCS RxMCS; + u16 last_transmit_rate; + u16 rssi; + u32 timestamp; + u8 tid; +} rx_aggr_stats; + + +typedef struct drv_msg_s +{ + u16 length; + u16 event_type; + u32 timestamp_low; + u32 timestamp_high; + union { + struct { + u32 version; + u32 msg_seq_no; + u32 payload_len; + u8 payload[0]; + } __attribute__((packed)) pkt_stats_event; + } u; +} __attribute__((packed)) drv_msg_t; + +typedef enum { + START_MONITOR = 1, + STOP_MONITOR, + TX_MGMT_PKT, + TX_DATA_PKT, + RX_MGMT_PKT, + RX_DATA_PKT, +} pktdump_event_type; + +typedef struct { + u8 status; + u8 type; + u32 driver_ts; + u16 fw_ts; +} __attribute__((packed)) pktdump_hdr; + +typedef struct { + frame_type payload_type; + u32 driver_timestamp_usec; + u32 firmware_timestamp_usec; + size_t frame_len; + char *frame_content; +} frame_info_i; + +typedef struct { + // Prefix of MD5 hash of |frame_inf.frame_content|. If frame + // content is not provided, prefix of MD5 hash over the same data + // that would be in frame_content, if frame content were provided. + char md5_prefix[MD5_PREFIX_LEN]; // Prefix of MD5 hash of packet bytes + wifi_tx_packet_fate fate; + frame_info_i frame_inf; +} wifi_tx_report_i; + +typedef struct { + // Prefix of MD5 hash of |frame_inf.frame_content|. If frame + // content is not provided, prefix of MD5 hash over the same data + // that would be in frame_content, if frame content were provided. + char md5_prefix[MD5_PREFIX_LEN]; + wifi_rx_packet_fate fate; + frame_info_i frame_inf; +} wifi_rx_report_i; + +typedef struct { + wifi_tx_report_i tx_fate_stats[MAX_FATE_LOG_LEN]; + size_t n_tx_stats_collected; + wifi_rx_report_i rx_fate_stats[MAX_FATE_LOG_LEN]; + size_t n_rx_stats_collected; +} packet_fate_monitor_info; + +#endif diff --git a/wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h b/wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h new file mode 100644 index 0000000..c13815b --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h @@ -0,0 +1,12217 @@ +/* + * Qualcomm Atheros OUI and vendor specific assignments + * Copyright (c) 2014-2017, Qualcomm Atheros, Inc. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#ifndef QCA_VENDOR_H +#define QCA_VENDOR_H + +/* + * This file is a registry of identifier assignments from the Qualcomm Atheros + * OUI 00:13:74 for purposes other than MAC address assignment. New identifiers + * can be assigned through normal review process for changes to the upstream + * hostap.git repository. + */ + +#define OUI_QCA 0x001374 + +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + +/** + * enum qca_radiotap_vendor_ids - QCA radiotap vendor namespace IDs + */ +enum qca_radiotap_vendor_ids { + QCA_RADIOTAP_VID_WLANTEST = 0, +}; + +/** + * enum qca_nl80211_vendor_subcmds - QCA nl80211 vendor command identifiers + * + * @QCA_NL80211_VENDOR_SUBCMD_UNSPEC: Reserved value 0 + * + * @QCA_NL80211_VENDOR_SUBCMD_TEST: Test command/event + * + * @QCA_NL80211_VENDOR_SUBCMD_ROAMING: Set roaming policy for drivers that use + * internal BSS-selection. This command uses + * @QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY to specify the new roaming policy + * for the current connection (i.e., changes policy set by the nl80211 + * Connect command). @QCA_WLAN_VENDOR_ATTR_MAC_ADDR may optionally be + * included to indicate which BSS to use in case roaming is disabled. + * + * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY: Recommendation of frequency + * ranges to avoid to reduce issues due to interference or internal + * co-existence information in the driver. These frequencies aim to + * minimize the traffic but not to totally avoid the traffic. That said + * for a P2P use case, these frequencies are allowed for the P2P + * discovery/negotiation but avoid the group to get formed on these + * frequencies. The event data structure is defined in + * struct qca_avoid_freq_list. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY: Command to check driver support + * for DFS offloading. + * + * @QCA_NL80211_VENDOR_SUBCMD_NAN: NAN command/event which is used to pass + * NAN Request/Response and NAN Indication messages. These messages are + * interpreted between the framework and the firmware component. While + * sending the command from userspace to the driver, payload is not + * encapsulated inside any attribute. Attribute QCA_WLAN_VENDOR_ATTR_NAN + * is used when receiving vendor events in userspace from the driver. + * + * @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY: Set key operation that can be + * used to configure PMK to the driver even when not connected. This can + * be used to request offloading of key management operations. Only used + * if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD. + * + * @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: An extended version of + * NL80211_CMD_ROAM event with optional attributes including information + * from offloaded key management operation. Uses + * enum qca_wlan_vendor_attr_roam_auth attributes. Only used + * if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD. + * + * @QCA_NL80211_VENDOR_SUBCMD_DO_ACS: ACS command/event which is used to + * invoke the ACS function in device and pass selected channels to + * hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Command to get the features + * supported by the driver. enum qca_wlan_vendor_features defines + * the possible features. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Event used by driver, + * which supports DFS offloading, to indicate a channel availability check + * start. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED: Event used by driver, + * which supports DFS offloading, to indicate a channel availability check + * completion. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED: Event used by driver, + * which supports DFS offloading, to indicate that the channel availability + * check aborted, no change to the channel status. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED: Event used by + * driver, which supports DFS offloading, to indicate that the + * Non-Occupancy Period for this channel is over, channel becomes usable. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED: Event used by driver, + * which supports DFS offloading, to indicate a radar pattern has been + * detected. The channel is now unusable. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO: Get information from the driver. + * Attributes defined in enum qca_wlan_vendor_attr_get_wifi_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET: Get the feature bitmap + * based on enum wifi_logger_supported_features. Attributes defined in + * enum qca_wlan_vendor_attr_get_logger_features. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA: Get the ring data from a particular + * logger ring, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID is passed as the + * attribute for this command. Attributes defined in + * enum qca_wlan_vendor_attr_wifi_logger_start. + * + * @QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES: Get the supported TDLS + * capabilities of the driver, parameters includes the attributes defined + * in enum qca_wlan_vendor_attr_tdls_get_capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS: Vendor command used to offload + * sending of certain periodic IP packet to firmware, attributes defined in + * enum qca_wlan_vendor_attr_offloaded_packets. + * + * @QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI: Command used to configure RSSI + * monitoring, defines min and max RSSI which are configured for RSSI + * monitoring. Also used to notify the RSSI breach and provides the BSSID + * and RSSI value that was breached. Attributes defined in + * enum qca_wlan_vendor_attr_rssi_monitoring. + * + * @QCA_NL80211_VENDOR_SUBCMD_NDP: Command used for performing various NAN + * Data Path (NDP) related operations, attributes defined in + * enum qca_wlan_vendor_attr_ndp_params. + * + * @QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD: Command used to enable/disable + * Neighbour Discovery offload, attributes defined in + * enum qca_wlan_vendor_attr_nd_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER: Used to set/get the various + * configuration parameter for BPF packet filter, attributes defined in + * enum qca_wlan_vendor_attr_packet_filter. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE: Gets the driver-firmware + * maximum supported size, attributes defined in + * enum qca_wlan_vendor_drv_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS: Command to get various + * data about wake reasons and datapath IP statistics, attributes defined + * in enum qca_wlan_vendor_attr_wake_stats. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG: Command used to set configuration + * for IEEE 802.11 communicating outside the context of a basic service + * set, called OCB command. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_set_config. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME: Command used to set OCB + * UTC time. Use the attributes defines in + * enum qca_wlan_vendor_attr_ocb_set_utc_time. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT: Command used to start + * sending OCB timing advert frames. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_start_timing_advert. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT: Command used to stop + * OCB timing advert. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_stop_timing_advert. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER: Command used to get TSF + * timer value. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_get_tsf_resp. + * + * @QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES: Command/event to update the + * link properties of the respective interface. As an event, is used + * to notify the connected station's status. The attributes for this + * command are defined in enum qca_wlan_vendor_attr_link_properties. + * + * @QCA_NL80211_VENDOR_SUBCMD_SETBAND: Command to configure the enabled band(s) + * to the driver. This command sets the band(s) through either the + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE or + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK (or both). + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE refers enum qca_set_band as unsigned + * integer values and QCA_WLAN_VENDOR_ATTR_SETBAND_MASK refers it as 32 + * bit unsigned bitmask values. The allowed values for + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE are limited to QCA_SETBAND_AUTO, + * QCA_SETBAND_5G, and QCA_SETBAND_2G. Other values/bitmasks are valid for + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. The attribute + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE is deprecated and the recommendation + * is to use the QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. If the both attributes + * are included for backwards compatibility, the configurations through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK will take the precedence with drivers + * that support both attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY: This command is used to configure + * DFS policy and channel hint for ACS operation. This command uses the + * attributes defined in enum qca_wlan_vendor_attr_acs_config and + * enum qca_acs_dfs_mode. + * + * @QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START: Command used to + * start the P2P Listen offload function in device and pass the listen + * channel, period, interval, count, device types, and vendor specific + * information elements to the device driver and firmware. + * Uses the attributes defines in + * enum qca_wlan_vendor_attr_p2p_listen_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP: Command/event used to + * indicate stop request/response of the P2P Listen offload function in + * device. As an event, it indicates either the feature stopped after it + * was already running or feature has actually failed to start. Uses the + * attributes defines in enum qca_wlan_vendor_attr_p2p_listen_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH: After AP starts + * beaconing, this sub command provides the driver, the frequencies on the + * 5 GHz band to check for any radar activity. Driver selects one channel + * from this priority list provided through + * @QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST and starts + * to check for radar activity on it. If no radar activity is detected + * during the channel availability check period, driver internally switches + * to the selected frequency of operation. If the frequency is zero, driver + * internally selects a channel. The status of this conditional switch is + * indicated through an event using the same sub command through + * @QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS. Attributes are + * listed in qca_wlan_vendor_attr_sap_conditional_chan_switch. + * + * @QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND: Set GPIO pins. This uses the + * attributes defined in enum qca_wlan_gpio_attr. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY: Fetch hardware capabilities. + * This uses @QCA_WLAN_VENDOR_ATTR_GET_HW_CAPABILITY to indicate which + * capabilities are to be fetched and other + * enum qca_wlan_vendor_attr_get_hw_capability attributes to return the + * requested capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT: Link layer statistics extension. + * enum qca_wlan_vendor_attr_ll_stats_ext attributes are used with this + * command and event. + * + * @QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA: Get capabilities for + * indoor location features. Capabilities are reported in + * QCA_WLAN_VENDOR_ATTR_LOC_CAPA. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION: Start an FTM + * (fine timing measurement) session with one or more peers. + * Specify Session cookie in QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE and + * peer information in QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS. + * On success, 0 or more QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT + * events will be reported, followed by + * QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE event to indicate + * end of session. + * Refer to IEEE P802.11-REVmc/D7.0, 11.24.6 + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION: Abort a running session. + * A QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE will be reported with + * status code indicating session was aborted. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT: Event with measurement + * results for one peer. Results are reported in + * QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE: Event triggered when + * FTM session is finished, either successfully or aborted by + * request. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER: Configure FTM responder + * mode. QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE specifies whether + * to enable or disable the responder. LCI/LCR reports can be + * configured with QCA_WLAN_VENDOR_ATTR_FTM_LCI and + * QCA_WLAN_VENDOR_ATTR_FTM_LCR. Can be called multiple + * times to update the LCI/LCR reports. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS: Perform a standalone AOA (angle of + * arrival) measurement with a single peer. Specify peer MAC address in + * QCA_WLAN_VENDOR_ATTR_MAC_ADDR and optionally frequency (MHz) in + * QCA_WLAN_VENDOR_ATTR_FREQ (if not specified, locate peer in kernel + * scan results cache and use the frequency from there). + * Also specify measurement type in QCA_WLAN_VENDOR_ATTR_AOA_TYPE. + * Measurement result is reported in + * QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT event. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS: Abort an AOA measurement. Specify + * peer MAC address in QCA_WLAN_VENDOR_ATTR_MAC_ADDR. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT: Event that reports + * the AOA measurement result. + * Peer MAC address reported in QCA_WLAN_VENDOR_ATTR_MAC_ADDR. + * success/failure status is reported in + * QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS. + * Measurement data is reported in QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT. + * The antenna array(s) used in the measurement are reported in + * QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK. + * + * @QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST: Encrypt/decrypt the given + * data as per the given parameters. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI: Get antenna RSSI value for a + * specific chain. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG: Get low level + * configuration for a DMG RF sector. Specify sector index in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX, sector type in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and RF modules + * to return sector information for in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_MODULE_MASK. Returns sector configuration + * in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG. Also return the + * exact time where information was captured in + * QCA_WLAN_VENDOR_ATTR_TSF. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG: Set low level + * configuration for a DMG RF sector. Specify sector index in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX, sector type in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and sector configuration + * for one or more DMG RF modules in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR: Get selected + * DMG RF sector for a station. This is the sector that the HW + * will use to communicate with the station. Specify the MAC address + * of associated station/AP/PCP in QCA_WLAN_VENDOR_ATTR_MAC_ADDR (not + * needed for unassociated station). Specify sector type to return in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE. Returns the selected + * sector index in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX. + * Also return the exact time where the information was captured + * in QCA_WLAN_VENDOR_ATTR_TSF. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR: Set the + * selected DMG RF sector for a station. This is the sector that + * the HW will use to communicate with the station. + * Specify the MAC address of associated station/AP/PCP in + * QCA_WLAN_VENDOR_ATTR_MAC_ADDR, the sector type to select in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and the sector index + * in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX. + * The selected sector will be locked such that it will not be + * modified like it normally does (for example when station + * moves around). To unlock the selected sector for a station + * pass the special value 0xFFFF in the sector index. To unlock + * all connected stations also pass a broadcast MAC address. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS: Configure the TDLS behavior + * in the host driver. The different TDLS configurations are defined + * by the attributes in enum qca_wlan_vendor_attr_tdls_configuration. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES: Query device IEEE 802.11ax HE + * capabilities. The response uses the attributes defined in + * enum qca_wlan_vendor_attr_get_he_capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN: Abort an ongoing vendor scan that was + * started with QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN. This command + * carries the scan cookie of the corresponding scan request. The scan + * cookie is represented by QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS: Set the Specific + * Absorption Rate (SAR) power limits. A critical regulation for + * FCC compliance, OEMs require methods to set SAR limits on TX + * power of WLAN/WWAN. enum qca_vendor_attr_sar_limits + * attributes are used with this command. + * + * @QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS: This command/event is used by the + * host driver for offloading the implementation of Auto Channel Selection + * (ACS) to an external user space entity. This interface is used as the + * event from the host driver to the user space entity and also as the + * request from the user space entity to the host driver. The event from + * the host driver is used by the user space entity as an indication to + * start the ACS functionality. The attributes used by this event are + * represented by the enum qca_wlan_vendor_attr_external_acs_event. + * User space entity uses the same interface to inform the host driver with + * selected channels after the ACS operation using the attributes defined + * by enum qca_wlan_vendor_attr_external_acs_channels. + * + * @QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE: Vendor event carrying the + * requisite information leading to a power save failure. The information + * carried as part of this event is represented by the + * enum qca_attr_chip_power_save_failure attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET: Start/Stop the NUD statistics + * collection. Uses attributes defined in enum qca_attr_nud_stats_set. + * + * @QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET: Get the NUD statistics. These + * statistics are represented by the enum qca_attr_nud_stats_get + * attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS: Sub-command to fetch + * the BSS transition status, whether accept or reject, for a list of + * candidate BSSIDs provided by the userspace. This uses the vendor + * attributes QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON and + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO. The userspace shall specify + * the attributes QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON and an + * array of QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID nested in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO in the request. In the response + * the driver shall specify array of + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID and + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS pairs nested in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL: Set the trace level for a + * specific QCA module. The trace levels are represented by + * enum qca_attr_trace_level attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT: Set the Beam Refinement + * Protocol antenna limit in different modes. See enum + * qca_wlan_vendor_attr_brp_ant_limit_mode. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START: Start spectral scan. The scan + * parameters are specified by enum qca_wlan_vendor_attr_spectral_scan. + * This returns a cookie (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE) + * identifying the operation in success case. In failure cases an + * error code (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE) + * describing the reason for the failure is returned. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP: Stop spectral scan. This uses + * a cookie (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE) from + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START to identify the scan to + * be stopped. + * + * @QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS: Set the active Type Of Service on the + * specific interface. This can be used to modify some of the low level + * scan parameters (off channel dwell time, home channel time) in the + * driver/firmware. These parameters are maintained within the host driver. + * This command is valid only when the interface is in the connected state. + * These scan parameters shall be reset by the driver/firmware once + * disconnected. The attributes used with this command are defined in + * enum qca_wlan_vendor_attr_active_tos. + * + * @QCA_NL80211_VENDOR_SUBCMD_HANG: Event indicating to the user space that the + * driver has detected an internal failure. This event carries the + * information indicating the reason that triggered this detection. The + * attributes for this command are defined in + * enum qca_wlan_vendor_attr_hang. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CONFIG: Get the current values + * of spectral parameters used. The spectral scan parameters are specified + * by enum qca_wlan_vendor_attr_spectral_scan. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS: Get the debug stats + * for spectral scan functionality. The debug stats are specified by + * enum qca_wlan_vendor_attr_spectral_diag_stats. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO: Get spectral + * scan system capabilities. The capabilities are specified + * by enum qca_wlan_vendor_attr_spectral_cap. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS: Get the current + * status of spectral scan. The status values are specified + * by enum qca_wlan_vendor_attr_spectral_scan_status. + * + * @QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING: Sub-command to flush + * peer pending packets. Specify the peer MAC address in + * QCA_WLAN_VENDOR_ATTR_PEER_ADDR and the access category of the packets + * in QCA_WLAN_VENDOR_ATTR_AC. The attributes are listed + * in enum qca_wlan_vendor_attr_flush_pending. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO: Get vendor specific Representative + * RF Operating Parameter (RROP) information. The attributes for this + * information are defined in enum qca_wlan_vendor_attr_rrop_info. This is + * intended for use by external Auto Channel Selection applications. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS: Get the Specific Absorption Rate + * (SAR) power limits. This is a companion to the command + * @QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS and is used to retrieve the + * settings currently in use. The attributes returned by this command are + * defined by enum qca_vendor_attr_sar_limits. + * + * @QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO: Provides the current behavior of + * the WLAN hardware MAC. Also, provides the WLAN netdev interface + * information attached to the respective MAC. + * This works both as a query (user space asks the current mode) or event + * interface (driver advertising the current mode to the user space). + * Driver does not trigger this event for temporary hardware mode changes. + * Mode changes w.r.t Wi-Fi connection update (VIZ creation / deletion, + * channel change, etc.) are updated with this event. Attributes for this + * interface are defined in enum qca_wlan_vendor_attr_mac. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH: Set MSDU queue depth threshold + * per peer per TID. Attributes for this command are define in + * enum qca_wlan_set_qdepth_thresh_attr. + * @QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD: Provides the thermal shutdown action + * guide for WLAN driver. Request to suspend of driver and FW if the + * temperature is higher than the suspend threshold; resume action is + * requested to driver if the temperature is lower than the resume + * threshold. In user poll mode, request temperature data by user. For test + * purpose, getting thermal shutdown configuration parameters is needed. + * Attributes for this interface are defined in + * enum qca_wlan_vendor_attr_thermal_cmd. + * @QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT: Thermal events reported from + * driver. Thermal temperature and indication of resume completion are + * reported as thermal events. The attributes for this command are defined + * in enum qca_wlan_vendor_attr_thermal_event. + * + * @QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION: Sub command to set WiFi + * test configuration. Attributes for this command are defined in + * enum qca_wlan_vendor_attr_wifi_test_config. + * + * @QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER: This command is used to configure an + * RX filter to receive frames from stations that are active on the + * operating channel, but not associated with the local device (e.g., STAs + * associated with other APs). Filtering is done based on a list of BSSIDs + * and STA MAC addresses added by the user. This command is also used to + * fetch the statistics of unassociated stations. The attributes used with + * this command are defined in enum qca_wlan_vendor_attr_bss_filter. + * + * @QCA_NL80211_VENDOR_SUBCMD_NAN_EXT: An extendable version of NAN vendor + * command. The earlier command for NAN, QCA_NL80211_VENDOR_SUBCMD_NAN, + * carried a payload which was a binary blob of data. The command was not + * extendable to send more information. The newer version carries the + * legacy blob encapsulated within an attribute and can be extended with + * additional vendor attributes that can enhance the NAN command interface. + * @QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT: Event to indicate scan triggered + * or stopped within driver/firmware in order to initiate roaming. The + * attributes used with this event are defined in enum + * qca_wlan_vendor_attr_roam_scan. Some drivers may not send these events + * in few cases, e.g., if the host processor is sleeping when this event + * is generated in firmware. + * + * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to + * configure parameters per peer to capture Channel Frequency Response + * (CFR) and enable Periodic CFR capture. The attributes for this command + * are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command + * can also be used to send CFR data from the driver to userspace when + * netlink events are used to send CFR data. + * + * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes + * in throughput dynamically. The driver estimates the throughput based on + * number of packets being transmitted/received per second and indicates + * the changes in throughput to user space. Userspace tools can use this + * information to configure kernel's TCP parameters in order to achieve + * peak throughput. Optionally, the driver will also send guidance on + * modifications to kernel's TCP parameters which can be referred by + * userspace tools. The attributes used with this event are defined in enum + * qca_wlan_vendor_attr_throughput_change. + * + * @QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG: This command is used to set + * priorities among different types of traffic during coex scenarios. + * Current supported prioritization is among WLAN/BT/ZIGBEE with different + * profiles mentioned in enum qca_coex_config_profiles. The associated + * attributes used with this command are defined in enum + * qca_vendor_attr_coex_config. + * + * Based on the config provided, FW will boost the weight and prioritize + * the traffic for that subsystem (WLAN/BT/Zigbee). + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS: This command is used to query + * the supported AKM suite selectorss from the driver. It returns the list + * of supported AKMs in the attribute NL80211_ATTR_AKM_SUITES. + * @QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE: This command is used to get firmware + * state from the driver. It returns the firmware state in the attribute + * QCA_WLAN_VENDOR_ATTR_FW_STATE. + * @QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH: This vendor subcommand + * is used by the driver to flush per-peer cached statistics to user space + * application. This interface is used as an event from the driver to + * user space application. Attributes for this event are specified in + * enum qca_wlan_vendor_attr_peer_stats_cache_params. + * QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA attribute is expected to be + * sent in the event. + * @QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG: This sub command is used to + * improve the success rate of Zigbee joining network. + * Due to PTA master limitation, Zigbee joining network success rate is + * low while WLAN is working. The WLAN driver needs to configure some + * parameters including Zigbee state and specific WLAN periods to enhance + * PTA master. All these parameters are delivered by the attributes + * defined in enum qca_mpta_helper_vendor_attr. + * @QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING: This sub command is used to + * implement Beacon frame reporting feature. + * + * Userspace can request the driver/firmware to periodically report + * received Beacon frames whose BSSID is same as the current connected + * BSS's MAC address. + * + * In case the STA seamlessly (without sending disconnect indication to + * userspace) roams to a different BSS, Beacon frame reporting will be + * automatically enabled for the Beacon frames whose BSSID is same as the + * MAC address of the new BSS. Beacon reporting will be stopped when the + * STA is disconnected (when the disconnect indication is sent to + * userspace) and need to be explicitly enabled by userspace for next + * connection. + * + * When a Beacon frame matching configured conditions is received, and if + * userspace has requested to send asynchronous beacon reports, the + * driver/firmware will encapsulate the details of the Beacon frame in an + * event and send it to userspace along with updating the BSS information + * in cfg80211 scan cache, otherwise driver will only update the cfg80211 + * scan cache with the information from the received Beacon frame but will + * not send any active report to userspace. + * + * The userspace can request the driver/firmware to stop reporting Beacon + * frames. If the driver/firmware is not able to receive Beacon frames due + * to other Wi-Fi operations such as off-channel activities, etc., the + * driver/firmware will send a pause event to userspace and stop reporting + * Beacon frames. Whether the beacon reporting will be automatically + * resumed or not by the driver/firmware later will be reported to + * userspace using the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES + * flag. The beacon reporting shall be resumed for all the cases except + * either when userspace sets + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_DO_NOT_RESUME flag in the command + * which triggered the current beacon reporting or during any disconnection + * case as indicated by setting + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON to + * QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED by the + * driver. + * + * After QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_PAUSE event is received + * by userspace with QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES + * flag not set, the next first + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO event from the driver + * shall be considered as un-pause event. + * + * All the attributes used with this command are defined in + * enum qca_wlan_vendor_attr_beacon_reporting_params. + * @QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP: In practice, some APs have + * interop issues with the DUT. This sub command is used to transfer the + * AP info between the driver and user space. This works both as a command + * and an event. As a command, it configures the stored list of APs from + * user space to firmware; as an event, it indicates the AP info detected + * by the firmware to user space for persistent storage. The attributes + * defined in enum qca_vendor_attr_interop_issues_ap are used to deliver + * the parameters. + * @QCA_NL80211_VENDOR_SUBCMD_OEM_DATA: This command/event is used to + * send/receive OEM data binary blobs to/from application/service to/from + * firmware. The attributes defined in enum + * qca_wlan_vendor_attr_oem_data_params are used to deliver the + * parameters. + * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT: This command/event is used + * to send/receive avoid frequency data using + * enum qca_wlan_vendor_attr_avoid_frequency_ext. + * This new command is alternative to existing command + * QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event + * is using stream of bytes instead of structured data using vendor + * attributes. User space sends unsafe frequency ranges to the driver using + * a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On + * reception of this command, the driver shall check if an interface is + * operating on an unsafe frequency and the driver shall try to move to a + * safe channel when needed. If the driver is not able to find a safe + * channel the interface can keep operating on an unsafe channel with the + * TX power limit derived based on internal configurations like + * regulatory/SAR rules. + * + * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to + * add the STA node details in driver/firmware. Attributes for this event + * are specified in enum qca_wlan_vendor_attr_add_sta_node_params. + * @QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE: This command is used to set BT + * coex chain mode from application/service. + * The attributes defined in enum qca_vendor_attr_btc_chain_mode are used + * to deliver the parameters. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO: This vendor subcommand is used to + * get information of a station from driver to userspace. This command can + * be used in both STA and AP modes. For STA mode, it provides information + * of the current association when in connected state or the last + * association when in disconnected state. For AP mode, only information + * of the currently connected stations is available. This command uses + * attributes defined in enum qca_wlan_vendor_attr_get_sta_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_REQUEST_SAR_LIMITS_EVENT: This acts as an event. + * Host drivers can request the user space entity to set the SAR power + * limits with this event. Accordingly, the user space entity is expected + * to set the SAR power limits. Host drivers can retry this event to the + * user space for the SAR power limits configuration from user space. If + * the driver does not get the SAR power limits from user space for all + * the retried attempts, it can configure a default SAR power limit. + * + * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO: This acts as a vendor event and + * is used to update the information about the station from the driver to + * userspace. Uses attributes from enum + * qca_wlan_vendor_attr_update_sta_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON: This acts as an event. + * The host driver initiates the disconnection for scenarios such as beacon + * miss, NUD failure, peer kick out, etc. The disconnection indication + * through cfg80211_disconnected() expects the reason codes from enum + * ieee80211_reasoncode which does not signify these various reasons why + * the driver has triggered the disconnection. This event will be used to + * send the driver specific reason codes by the host driver to userspace. + * Host drivers should trigger this event and pass the respective reason + * code immediately prior to triggering cfg80211_disconnected(). The + * attributes used with this event are defined in enum + * qca_wlan_vendor_attr_driver_disconnect_reason. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC: This vendor subcommand is used to + * add/delete TSPEC for each AC. One command is for one specific AC only. + * This command can only be used in STA mode and the STA must be + * associated with an AP when the command is issued. Uses attributes + * defined in enum qca_wlan_vendor_attr_config_tspec. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT. + * Uses attributes defined in enum qca_wlan_vendor_attr_config_twt. + * + * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the enabled band(s) from + * the driver. The band configurations obtained are referred through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. + * + * @QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS: Vendor subcommand/event for medium + * assessment. + * Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess. + * + * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID: This acts as a vendor event and is + * used to update SSID information in hostapd when it is updated in the + * driver. Uses the attribute NL80211_ATTR_SSID. + * + * @QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS: This vendor subcommand is used by + * the driver to send opaque data from the firmware to userspace. The + * driver sends an event to userspace whenever such data is received from + * the firmware. + * + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to + * send this opaque data for this event. + * + * The format of the opaque data is specific to the particular firmware + * version and there is no guarantee of the format remaining same. + * + * @QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS: This acts as an event. + * The host driver selects Tx VDEV, and notifies user. The attributes + * used with this event are defined in enum + * qca_wlan_vendor_attr_mbssid_tx_vdev_status. + * This event contains Tx VDEV group information, other VDEVs + * interface index, and status information. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to + * configure the concurrent session policies when multiple STA interfaces + * are (getting) active. The attributes used by this command are defined + * in enum qca_wlan_vendor_attr_concurrent_sta_policy. + * + * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command + * to query usable channels for different interface types such as STA, + * AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable + * channels in the response based on country code, different static + * configurations, concurrency combinations, etc. The attributes used + * with this command are defined in + * enum qca_wlan_vendor_attr_usable_channels. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used + * to get DFS radar history from the driver to userspace. The driver + * returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an + * array of nested entries. + * + * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to + * enable/disable mDNS offload to the firmware. The attributes used with + * this command are defined in enum qca_wlan_vendor_attr_mdns_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used + * to set packet monitor mode that aims to send the specified set of TX and + * RX frames on the current client interface to an active monitor + * interface. If this monitor mode is set, the driver will send the + * configured frames, from the interface on which the command is issued, to + * an active monitor interface. The attributes used with this command are + * defined in enum qca_wlan_vendor_attr_set_monitor_mode. + * + * Though the monitor mode is configured for the respective + * Data/Management/Control frames, it is up to the respective WLAN + * driver/firmware/hardware designs to consider the possibility of sending + * these frames over the monitor interface. For example, the Control frames + * are handled within the hardware and thus passing such frames over the + * monitor interface is left to the respective designs. + * + * Also, this monitor mode is governed to behave accordingly in + * suspend/resume states. If the firmware handles any of such frames in + * suspend state without waking up the host and if the monitor mode is + * configured to notify all such frames, the firmware is expected to resume + * the host and forward the respective frames to the monitor interface. + * Please note that such a request to get the frames over the monitor + * interface will have a definite power implication. + * + * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both + * as a request to set the driver/firmware with the parameters to trigger + * the roaming events, and also used by the driver/firmware to pass on the + * various roam events to userspace. + * Applicable only for the STA mode. The attributes used with this command + * are defined in enum qca_wlan_vendor_attr_roam_events. + * + * @QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG: Subcommand to set or reset the + * rate mask config for a list of PHY types. Userspace shall provide an + * array of the vendor attributes defined in + * enum qca_wlan_vendor_attr_ratemask_params. + * + * @QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA: Multi-channel Concurrency (MCC) occurs + * when two interfaces are active on the same band, using two different + * home channels, and only supported by a single radio. In this scenario + * the device must split the use of the radio between the two interfaces. + * The percentage of time allocated to a given interface is the quota. + * Depending on the configuration, the quota can either be fixed or + * dynamic. + * + * When used as an event, the device will report the quota type, and for + * all interfaces operating in MCC it will report the current quota. + * When used as a command, the device can be configured for a specific + * quota type, and in the case of a fixed quota, the quota to apply to one + * of the interfaces. + * + * Applications can use the event to do TX bitrate control based on the + * information, and can use the command to explicitly set the quota to + * enhance performance in specific scenarios. + * + * The attributes used with this command are defined in + * enum qca_wlan_vendor_attr_mcc_quota. + */ +enum qca_nl80211_vendor_subcmds { + QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0, + QCA_NL80211_VENDOR_SUBCMD_TEST = 1, + /* subcmds 2..8 not yet allocated */ + QCA_NL80211_VENDOR_SUBCMD_ROAMING = 9, + 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, + 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, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_START = 20, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP = 21, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS = 22, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES = 23, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS = 24, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE = 25, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT = 26, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT = 27, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND = 28, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST = 29, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST = 30, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE = 31, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE = 32, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE = 33, + 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, + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38, + QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI = 39, + QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG = 40, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST = 41, + QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42, + /* 43..49 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY = 50, + QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH = 51, + QCA_NL80211_VENDOR_SUBCMD_APFIND = 52, + /* 53 - reserved - was used by QCA, but not in use anymore */ + QCA_NL80211_VENDOR_SUBCMD_DO_ACS = 54, + QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES = 55, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED = 56, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED = 57, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED = 58, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED = 59, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED = 60, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO = 61, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START = 62, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP = 63, + QCA_NL80211_VENDOR_SUBCMD_ROAM = 64, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST = 65, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SSID_HOTLIST = 66, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND = 67, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST = 68, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST = 69, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST = 70, + QCA_NL80211_VENDOR_SUBCMD_PNO_RESET_PASSPOINT_LIST = 71, + QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND = 72, + QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND = 73, + /* Wi-Fi configuration subcommands */ + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION = 74, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION = 75, + QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET = 76, + QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA = 77, + QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES = 78, + QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS = 79, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80, + QCA_NL80211_VENDOR_SUBCMD_NDP = 81, + QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD = 82, + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83, + QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE = 84, + QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS = 85, + /* 86-90 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_DATA_OFFLOAD = 91, + QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92, + QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93, + QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT = 94, + QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT = 95, + QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER = 96, + QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS = 97, + QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS = 98, + QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL = 99, + QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT = 100, + QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101, + QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG = 102, + QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103, + QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL = 104, + QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105, + QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN = 106, + QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE = 107, + QCA_NL80211_VENDOR_SUBCMD_OTA_TEST = 108, + QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE = 109, + /* 110..114 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_DECR_DB = 115, + QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116, + /* 117 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG = 118, + QCA_NL80211_VENDOR_SUBCMD_TSF = 119, + QCA_NL80211_VENDOR_SUBCMD_WISA = 120, + /* 121 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START = 122, + QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP = 123, + QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH = 124, + QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND = 125, + QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY = 126, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT = 127, + /* FTM/indoor location subcommands */ + QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA = 128, + QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION = 129, + QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION = 130, + QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT = 131, + QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE = 132, + QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER = 133, + QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS = 134, + QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS = 135, + QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT = 136, + QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST = 137, + QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI = 138, + /* DMG low level RF sector operations */ + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG = 139, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG = 140, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR = 141, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR = 142, + QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS = 143, + QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES = 144, + QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN = 145, + QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS = 146, + QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS = 147, + QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE = 148, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150, + QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS = 151, + QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL = 152, + QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT = 153, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START = 154, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP = 155, + QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS = 156, + QCA_NL80211_VENDOR_SUBCMD_HANG = 157, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CONFIG = 158, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS = 159, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO = 160, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS = 161, + /* Flush peer pending data */ + QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING = 162, + QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO = 163, + QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS = 164, + QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO = 165, + QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH = 166, + /* Thermal shutdown commands to protect wifi chip */ + QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD = 167, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT = 168, + /* Wi-Fi test configuration subcommand */ + QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION = 169, + /* Frame filter operations for other BSSs/unassociated STAs */ + QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER = 170, + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT = 171, + QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT = 172, + QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG = 173, + QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT = 174, + QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG = 175, + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS = 176, + QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE = 177, + QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH = 178, + QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG = 179, + QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING = 180, + QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP = 181, + QCA_NL80211_VENDOR_SUBCMD_OEM_DATA = 182, + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT = 183, + QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE = 184, + QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE = 185, + QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO = 186, + QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS_EVENT = 187, + QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO = 188, + QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON = 189, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC = 190, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT = 191, + QCA_NL80211_VENDOR_SUBCMD_GETBAND = 192, + QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS = 193, + QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194, + QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195, + QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196, + QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197, + QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198, + QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199, + QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200, + /* 201 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202, + QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203, + QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG = 204, + QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA = 205, +}; + +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 only when driver sends vendor events to the userspace under the + * command QCA_NL80211_VENDOR_SUBCMD_NAN. Not used when userspace sends + * commands to the driver. + */ + QCA_WLAN_VENDOR_ATTR_NAN = 2, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, + /* used by QCA_NL80211_VENDOR_SUBCMD_ROAMING, u32 with values defined + * by enum qca_roaming_policy. + */ + QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5, + QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6, + /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ + QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7, + QCA_WLAN_VENDOR_ATTR_TEST = 8, + /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA = 9, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND = 10, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND = 11, + /* Unsigned 32-bit value from enum qca_set_band. The allowed values for + * this attribute are limited to QCA_SETBAND_AUTO, QCA_SETBAND_5G, and + * QCA_SETBAND_2G. This attribute is deprecated. Recommendation is to + * use QCA_WLAN_VENDOR_ATTR_SETBAND_MASK instead. + */ + QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12, + /* Dummy (NOP) attribute for 64 bit padding */ + QCA_WLAN_VENDOR_ATTR_PAD = 13, + /* Unique FTM session cookie (Unsigned 64 bit). Specified in + * QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION. Reported in + * the session in QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT and + * QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE. + */ + QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE = 14, + /* Indoor location capabilities, returned by + * QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA. + * see enum qca_wlan_vendor_attr_loc_capa. + */ + QCA_WLAN_VENDOR_ATTR_LOC_CAPA = 15, + /* Array of nested attributes containing information about each peer + * in FTM measurement session. See enum qca_wlan_vendor_attr_peer_info + * for supported attributes for each peer. + */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS = 16, + /* Array of nested attributes containing measurement results for + * one or more peers, reported by the + * QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT event. + * See enum qca_wlan_vendor_attr_peer_result for list of supported + * attributes. + */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS = 17, + /* Flag attribute for enabling or disabling responder functionality. */ + QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE = 18, + /* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * command to specify the LCI report that will be sent by + * the responder during a measurement exchange. The format is + * defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.10. + */ + QCA_WLAN_VENDOR_ATTR_FTM_LCI = 19, + /* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * command to specify the location civic report that will + * be sent by the responder during a measurement exchange. + * The format is defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.13. + */ + QCA_WLAN_VENDOR_ATTR_FTM_LCR = 20, + /* Session/measurement completion status code, + * reported in QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE and + * QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT + * see enum qca_vendor_attr_loc_session_status. + */ + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS = 21, + /* Initial dialog token used by responder (0 if not specified), + * unsigned 8 bit value. + */ + QCA_WLAN_VENDOR_ATTR_FTM_INITIAL_TOKEN = 22, + /* AOA measurement type. Requested in QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS + * and optionally in QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION if + * AOA measurements are needed as part of an FTM session. + * Reported by QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT. See + * enum qca_wlan_vendor_attr_aoa_type. + */ + QCA_WLAN_VENDOR_ATTR_AOA_TYPE = 23, + /* A bit mask (unsigned 32 bit value) of antenna arrays used + * by indoor location measurements. Refers to the antenna + * arrays described by QCA_VENDOR_ATTR_LOC_CAPA_ANTENNA_ARRAYS. + */ + QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK = 24, + /* AOA measurement data. Its contents depends on the AOA measurement + * type and antenna array mask: + * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: array of U16 values, + * phase of the strongest CIR path for each antenna in the measured + * array(s). + * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16 + * values, phase and amplitude of the strongest CIR path for each + * antenna in the measured array(s). + */ + QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT = 25, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to specify the chain number (unsigned 32 bit value) to inquire + * the corresponding antenna RSSI value + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_INDEX = 26, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to report the specific antenna RSSI value (unsigned 32 bit value) + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI = 27, + /* Frequency in MHz, various uses. Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_FREQ = 28, + /* TSF timer value, unsigned 64 bit value. + * May be returned by various commands. + */ + QCA_WLAN_VENDOR_ATTR_TSF = 29, + /* DMG RF sector index, unsigned 16 bit number. Valid values are + * 0..127 for sector indices or 65535 as special value used to + * unlock sector selection in + * QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX = 30, + /* DMG RF sector type, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_attr_dmg_rf_sector_type. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE = 31, + /* Bitmask of DMG RF modules for which information is requested. Each + * bit corresponds to an RF module with the same index as the bit + * number. Unsigned 32 bit number but only low 8 bits can be set since + * all DMG chips currently have up to 8 RF modules. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_MODULE_MASK = 32, + /* Array of nested attributes where each entry is DMG RF sector + * configuration for a single RF module. + * Attributes for each entry are taken from enum + * qca_wlan_vendor_attr_dmg_rf_sector_cfg. + * Specified in QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG + * and returned by QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG = 33, + /* Used in QCA_NL80211_VENDOR_SUBCMD_STATS_EXT command + * to report frame aggregation statistics to userspace. + */ + QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM = 34, + QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO = 35, + /* Unsigned 8-bit value representing MBO transition reason code as + * provided by the AP used by subcommand + * QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS. This is + * specified by the userspace in the request to the driver. + */ + QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON = 36, + /* Array of nested attributes, BSSID and status code, used by subcommand + * QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS, where each + * entry is taken from enum qca_wlan_vendor_attr_btm_candidate_info. + * The userspace space specifies the list/array of candidate BSSIDs in + * the order of preference in the request. The driver specifies the + * status code, for each BSSID in the list, in the response. The + * acceptable candidates are listed in the order preferred by the + * driver. + */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO = 37, + /* Used in QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT command + * See enum qca_wlan_vendor_attr_brp_ant_limit_mode. + */ + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE = 38, + /* Used in QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT command + * to define the number of antennas to use for BRP. + * different purpose in each ANT_LIMIT_MODE: + * DISABLE - ignored + * EFFECTIVE - upper limit to number of antennas to be used + * FORCE - exact number of antennas to be used + * unsigned 8 bit value + */ + QCA_WLAN_VENDOR_ATTR_BRP_ANT_NUM_LIMIT = 39, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to report the corresponding antenna index to the chain RSSI value + */ + QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO = 40, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command to report + * the specific antenna EVM value (unsigned 32 bit value). With a + * determinate group of antennas, the driver specifies the EVM value + * for each antenna ID, and application extract them in user space. + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_EVM = 41, + /* + * Used in QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE command to report + * wlan firmware current state. FW state is an unsigned 8 bit value, + * one of the values in enum qca_wlan_vendor_attr_fw_state. + */ + QCA_WLAN_VENDOR_ATTR_FW_STATE = 42, + + /* Unsigned 32-bitmask value from enum qca_set_band. Substitutes the + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE for which only a subset + * of single values from enum qca_set_band are valid. This attribute + * uses bitmask combinations to define the respective allowed band + * combinations and this attributes takes precedence over + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE if both attributes are included. + */ + QCA_WLAN_VENDOR_ATTR_SETBAND_MASK = 43, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1, +}; + +enum qca_roaming_policy { + QCA_ROAMING_NOT_ALLOWED, + QCA_ROAMING_ALLOWED_WITHIN_ESS, +}; + +/** + * enum qca_roam_reason - Represents the reason codes for roaming. Used by + * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON. + * + * @QCA_ROAM_REASON_UNKNOWN: Any reason that do not classify under the below + * reasons. + * + * @QCA_ROAM_REASON_PER: Roam triggered when packet error rates (PER) breached + * the configured threshold. + * + * @QCA_ROAM_REASON_BEACON_MISS: Roam triggered due to the continuous configured + * beacon misses from the then connected AP. + * + * @QCA_ROAM_REASON_POOR_RSSI: Roam triggered due to the poor RSSI reported + * by the connected AP. + * + * @QCA_ROAM_REASON_BETTER_RSSI: Roam triggered for finding a BSS with a better + * RSSI than the connected BSS. Here the RSSI of the current BSS is not poor. + * + * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel + * or environment being very noisy or congested. + * + * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request + * from the user (user space). + * + * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from + * the connected AP. + * + * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization + * breaching out the configured threshold. + * + * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS + * transition request. + * + * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no + * data activity with the AP and the current RSSI falls below a certain + * threshold. + * + * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or + * Disassociation frames received from the connected AP. + * + * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan + * that happens when there is no candidate AP found during the poor RSSI scan + * trigger. + * + * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results + * obtained from an external scan (not aimed at roaming). + * + * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is + * established when the station is connected in the 2.4 GHz band. + */ +enum qca_roam_reason { + QCA_ROAM_REASON_UNKNOWN, + QCA_ROAM_REASON_PER, + QCA_ROAM_REASON_BEACON_MISS, + QCA_ROAM_REASON_POOR_RSSI, + QCA_ROAM_REASON_BETTER_RSSI, + QCA_ROAM_REASON_CONGESTION, + QCA_ROAM_REASON_USER_TRIGGER, + QCA_ROAM_REASON_BTM, + QCA_ROAM_REASON_BSS_LOAD, + QCA_ROAM_REASON_WTC, + QCA_ROAM_REASON_IDLE, + QCA_ROAM_REASON_DISCONNECTION, + QCA_ROAM_REASON_PERIODIC_TIMER, + QCA_ROAM_REASON_BACKGROUND_SCAN, + QCA_ROAM_REASON_BT_ACTIVITY, +}; + +enum qca_wlan_vendor_attr_roam_auth { + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS, + /* Indicates the status of re-association requested by user space for + * the BSSID specified by QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID. + * Type u16. + * Represents the status code from AP. Use + * %WLAN_STATUS_UNSPECIFIED_FAILURE if the device cannot give you the + * real status code for failures. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_STATUS, + /* This attribute indicates that the old association was maintained when + * a re-association is requested by user space and that re-association + * attempt fails (i.e., cannot connect to the requested BSS, but can + * remain associated with the BSS with which the association was in + * place when being requested to roam). Used along with + * WLAN_VENDOR_ATTR_ROAM_AUTH_STATUS to indicate the current + * re-association status. Type flag. + * This attribute is applicable only for re-association failure cases. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RETAIN_CONNECTION, + /* This attribute specifies the PMK if one was newly generated during + * FILS roaming. This is added to the PMKSA cache and is used in + * subsequent connections with PMKSA caching. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK = 11, + /* This attribute specifies the PMKID used/generated for the current + * FILS roam. This is used in subsequent connections with PMKSA caching. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID = 12, + /* A 16-bit unsigned value specifying the next sequence number to use + * in ERP message in the currently associated realm. This is used in + * doing subsequent ERP based connections in the same realm. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM = 13, + /* A 16-bit unsigned value representing the reasons for the roaming. + * Defined by enum qca_roam_reason. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON = 14, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_p2p_listen_offload { + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INVALID = 0, + /* A 32-bit unsigned value; the P2P listen frequency (MHz); must be one + * of the social channels. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL, + /* A 32-bit unsigned value; the P2P listen offload period (ms). + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD, + /* A 32-bit unsigned value; the P2P listen interval duration (ms). + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL, + /* A 32-bit unsigned value; number of interval times the firmware needs + * to run the offloaded P2P listen operation before it stops. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT, + /* An array of arbitrary binary data with one or more 8-byte values. + * The device types include both primary and secondary device types. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES, + /* An array of unsigned 8-bit characters; vendor information elements. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE, + /* A 32-bit unsigned value; a control flag to indicate whether listen + * results need to be flushed to wpa_supplicant. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG, + /* A 8-bit unsigned value; reason code for P2P listen offload stop + * event. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_acs_offload - Defines attributes to be used with + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL: Required (u8). + * Used with event to notify the primary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY instead. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL: Required (u8). + * Used with event to notify the secondary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is still used if either of + * the driver or user space application doesn't support 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE: Required (u8). + * (a) Used with command to configure hw_mode from + * enum qca_wlan_vendor_acs_hw_mode for ACS operation. + * (b) Also used with event to notify the hw_mode of selected primary channel + * in ACS operation. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT mode. + * Disable (flag attribute not present) - HT disabled and + * Enable (flag attribute present) - HT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT40 mode. + * Disable (flag attribute not present) - HT40 disabled and + * Enable (flag attribute present) - HT40 enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for VHT mode. + * Disable (flag attribute not present) - VHT disabled and + * Enable (flag attribute present) - VHT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH: Optional (u16) with command and + * mandatory with event. + * If specified in command path, ACS operation is configured with the given + * channel width (in MHz). + * In event path, specifies the channel width of the primary channel selected. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure channel list using an array of + * channel numbers (u8). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver mandates use of QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST whereas + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is optional. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 0 center channel number selected in + * ACS operation. The value is the index of the channel center frequency for + * 20 MHz, 40 MHz, and 80 MHz channels. The value is the center frequency index + * of the primary 80 MHz segment for 160 MHz and 80+80 MHz channels. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 1 center channel number selected in + * ACS operation. The value is zero for 20 MHz, 40 MHz, and 80 MHz channels. + * The value is the index of the channel center frequency for 160 MHz channels + * and the center frequency index of the secondary 80 MHz segment for 80+80 MHz + * channels. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure the channel list using an array of channel + * center frequencies in MHz (u32). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver first parses the frequency list and if it fails to get a frequency + * list, parses the channel list specified using + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST (considers only 2 GHz and 5 GHz channels in + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST). + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY: Required (u32). + * Used with event to notify the primary channel center frequency (MHz) selected + * in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY: Required (u32). + * Used with event to notify the secondary channel center frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 0 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 1 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED: Flag attribute. + * Used with command to notify the driver of EDMG request for ACS + * operation. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL: Optional (u8). + * Used with event to notify the EDMG channel number selected in ACS + * operation. + * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16). + * Used with event to notify the puncture pattern selected in ACS operation. + * Encoding for this attribute will follow the convention used in the Disabled + * Subchannel Bitmap field of the EHT Operation IE. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for EHT mode. + * Disable (flag attribute not present) - EHT disabled and + * Enable (flag attribute present) - EHT enabled. + */ +enum qca_wlan_vendor_attr_acs_offload { + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL = 1, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL = 2, + QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE = 3, + QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED = 4, + QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED = 5, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED = 6, + QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH = 7, + QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST = 8, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL = 9, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL = 10, + QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST = 11, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY = 12, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY = 13, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY = 14, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15, + QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16, + QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17, + QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18, + QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED = 19, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ACS_MAX = + QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_acs_hw_mode - Defines HW mode to be used with the + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. + * + * @QCA_ACS_MODE_IEEE80211B: 802.11b mode + * @QCA_ACS_MODE_IEEE80211G: 802.11g mode + * @QCA_ACS_MODE_IEEE80211A: 802.11a mode + * @QCA_ACS_MODE_IEEE80211AD: 802.11ad mode + * @QCA_ACS_MODE_IEEE80211ANY: all modes + * @QCA_ACS_MODE_IEEE80211AX: 802.11ax mode + */ +enum qca_wlan_vendor_acs_hw_mode { + QCA_ACS_MODE_IEEE80211B, + QCA_ACS_MODE_IEEE80211G, + QCA_ACS_MODE_IEEE80211A, + QCA_ACS_MODE_IEEE80211AD, + QCA_ACS_MODE_IEEE80211ANY, + QCA_ACS_MODE_IEEE80211AX, +}; + +/** + * enum qca_wlan_vendor_features - Vendor device/driver feature flags + * + * @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key + * management offload, a mechanism where the station's firmware + * does the exchange with the AP to establish the temporal keys + * after roaming, rather than having the user space wpa_supplicant do it. + * @QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY: Device supports automatic + * band selection based on channel selection results. + * @QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS: Device supports + * simultaneous off-channel operations. + * @QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD: Device supports P2P + * Listen offload; a mechanism where the station's firmware takes care of + * responding to incoming Probe Request frames received from other P2P + * Devices whilst in Listen state, rather than having the user space + * wpa_supplicant do it. Information from received P2P requests are + * forwarded from firmware to host whenever the host processor wakes up. + * @QCA_WLAN_VENDOR_FEATURE_OCE_STA: Device supports all OCE non-AP STA + * specific features. + * @QCA_WLAN_VENDOR_FEATURE_OCE_AP: Device supports all OCE AP specific + * features. + * @QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON: Device supports OCE STA-CFON + * specific features only. If a Device sets this bit but not the + * %QCA_WLAN_VENDOR_FEATURE_OCE_AP, the userspace shall assume that + * this Device may not support all OCE AP functionalities but can support + * only OCE STA-CFON functionalities. + * @QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY: Device supports self + * managed regulatory. + * @QCA_WLAN_VENDOR_FEATURE_TWT: Device supports TWT (Target Wake Time). + * @QCA_WLAN_VENDOR_FEATURE_11AX: Device supports 802.11ax (HE) + * @QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT: Device supports 6 GHz band operation + * @QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG: Device is capable of receiving + * and applying thermal configuration through + * %QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and + * %QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from + * userspace. + * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r. + * With Adaptive 11r feature, access points advertise the vendor + * specific IEs and MDE but do not include FT AKM in the RSNE. + * The Adaptive 11r supported stations are expected to identify + * such vendor specific IEs and connect to the AP in FT mode though + * the profile is configured in non-FT mode. + * The driver-based SME cases also need to have this support for + * Adaptive 11r to handle the connection and roaming scenarios. + * This flag indicates the support for the same to the user space. + * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports + * concurrent network sessions on different Wi-Fi bands. This feature + * capability is attributed to the hardware's capability to support + * the same (e.g., DBS). + * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the + * responses for the respective TWT operations are asynchronous (separate + * event message) from the driver. If not specified, the responses are + * synchronous (in vendor command reply) to the request. Each TWT + * operation is specifically mentioned (against its respective + * documentation) to support either of these or both modes. + * @QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI: Flag indicates + * that the driver requires add/del virtual interface path using the + * generic nl80211 commands for NDP interface create/delete and to + * register/unregister the netdev instead of creating/deleting the NDP + * interface using the vendor commands + * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE and + * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE. With the latest kernel + * (5.12 version onward), interface creation/deletion is not allowed using + * vendor commands as it leads to a deadlock while acquiring the RTNL_LOCK + * during the register/unregister of netdev. Create and delete NDP + * interface using NL80211_CMD_NEW_INTERFACE and NL80211_CMD_DEL_INTERFACE + * commands respectively if the driver advertises this capability set. + * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits + */ +enum qca_wlan_vendor_features { + QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0, + QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1, + QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS = 2, + QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD = 3, + QCA_WLAN_VENDOR_FEATURE_OCE_STA = 4, + QCA_WLAN_VENDOR_FEATURE_OCE_AP = 5, + QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON = 6, + QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY = 7, + QCA_WLAN_VENDOR_FEATURE_TWT = 8, + QCA_WLAN_VENDOR_FEATURE_11AX = 9, + QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT = 10, + QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG = 11, + QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R = 12, + QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13, + QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT = 14, + QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI = 15, + NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */ +}; + +/** + * enum qca_wlan_vendor_attr_data_offload_ind - Vendor Data Offload Indication + * + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION: Session corresponding to + * the offloaded data. + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL: Protocol of the offloaded + * data. + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT: Event type for the data offload + * indication. + */ +enum qca_wlan_vendor_attr_data_offload_ind { + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_MAX = + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_set_config - Vendor subcmd attributes to set + * OCB config + * + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT: Number of channels in the + * configuration + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE: Size of the schedule + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY: Array of channels + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY: Array of channels to be + * scheduled + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY: Array of NDL channel + * information + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY: Array of NDL + * active state configuration + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS: Configuration flags such as + * OCB_CONFIG_FLAG_80211_FRAME_MODE + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM: Default TX parameters to + * use in the case that a packet is sent without a TX control header + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION: Max duration after the + * last TA received that the local time set by TA is synchronous to other + * communicating OCB STAs. + */ +enum qca_wlan_vendor_attr_ocb_set_config { + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT = 1, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE = 2, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY = 3, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY = 4, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY = 5, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY = 6, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS = 7, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM = 8, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_set_utc_time - Vendor subcmd attributes to set + * UTC time + * + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE: The UTC time as an array of + * 10 bytes + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR: The time error as an array of + * 5 bytes + */ +enum qca_wlan_vendor_attr_ocb_set_utc_time { + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE = 1, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR = 2, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_start_timing_advert - Vendor subcmd attributes + * to start sending timing advert frames + * + * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ: Cannel frequency + * on which to send the frames + * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE: Number of times + * the frame is sent in 5 seconds + */ +enum qca_wlan_vendor_attr_ocb_start_timing_advert { + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE = 2, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_stop_timing_advert - Vendor subcmd attributes + * to stop timing advert + * + * @QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ: The channel + * frequency on which to stop the timing advert + */ +enum qca_wlan_vendor_attr_ocb_stop_timing_advert { + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_get_tsf_response - Vendor subcmd attributes to + * get TSF timer value + * + * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH: Higher 32 bits of the + * timer + * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW: Lower 32 bits of the timer + */ +enum qca_wlan_vendor_attr_ocb_get_tsf_resp { + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH = 1, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW = 2, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST - 1 +}; + +enum qca_vendor_attr_get_preferred_freq_list { + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID, + /* A 32-unsigned value; the interface type/mode for which the preferred + * frequency list is requested (see enum qca_iface_type for possible + * values); used in GET_PREFERRED_FREQ_LIST command from user-space to + * kernel and in the kernel response back to user-space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE, + /* An array of 32-unsigned values; values are frequency (MHz); sent + * from kernel space to user space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST, + /* An array of nested values as per enum qca_wlan_vendor_attr_pcl + * attribute. Each element contains frequency (MHz), weight, and flag + * bit mask indicating how the frequency should be used in P2P + * negotiation; sent from kernel space to user space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_WEIGHED_PCL, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX = + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST - 1 +}; + +enum qca_vendor_attr_probable_oper_channel { + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_INVALID, + /* 32-bit unsigned value; indicates the connection/iface type likely to + * come on this channel (see enum qca_iface_type). + */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE, + /* 32-bit unsigned value; the frequency (MHz) of the probable channel */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX = + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST - 1 +}; + +enum qca_iface_type { + QCA_IFACE_TYPE_STA, + QCA_IFACE_TYPE_AP, + QCA_IFACE_TYPE_P2P_CLIENT, + QCA_IFACE_TYPE_P2P_GO, + QCA_IFACE_TYPE_IBSS, + QCA_IFACE_TYPE_TDLS, +}; + +enum qca_set_band { + QCA_SETBAND_AUTO = 0, + QCA_SETBAND_5G = BIT(0), + QCA_SETBAND_2G = BIT(1), + QCA_SETBAND_6G = BIT(2), +}; + +/** + * enum qca_access_policy - Access control policy + * + * Access control policy is applied on the configured IE + * (QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE). + * To be set with QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY. + * + * @QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED: Deny Wi-Fi connections which match + * the specific configuration (IE) set, i.e., allow all the + * connections which do not match the configuration. + * @QCA_ACCESS_POLICY_DENY_UNLESS_LISTED: Accept Wi-Fi connections which match + * the specific configuration (IE) set, i.e., deny all the + * connections which do not match the configuration. + */ +enum qca_access_policy { + QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED, + QCA_ACCESS_POLICY_DENY_UNLESS_LISTED, +}; + +/** + * enum qca_vendor_attr_tsf_cmd: Vendor attributes for TSF capture + * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: Required (u32) + * Specify the TSF command. Possible values are defined in + * &enum qca_tsf_cmd. + * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Optional (u64) + * This attribute contains TSF timer value. This attribute is only available + * in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response. + * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Optional (u64) + * This attribute contains SOC timer value at TSF capture. This attribute is + * only available in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response. + * @QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL: Optional (u32) + * This attribute is used to provide TSF sync interval and only applicable when + * TSF command is %QCA_TSF_SYNC_START. If this attribute is not provided, the + * driver will use the default value. Time unit is in milliseconds. + */ +enum qca_vendor_attr_tsf_cmd { + QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TSF_CMD, + QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE, + QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE, + QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL, + QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TSF_MAX = + QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1 +}; + +/** + * enum qca_tsf_cmd: TSF driver commands + * @QCA_TSF_CAPTURE: Initiate TSF Capture + * @QCA_TSF_GET: Get TSF capture value + * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value + * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target + * will automatically send TSF report to the host. To query + * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be + * initiated first. + * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target + * will not automatically send TSF report to the host. If + * %QCA_TSF_AUTO_REPORT_ENABLE is initiated and + * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this + * operation needs to be initiated. + * @QCA_TSF_SYNC_START: Start periodic TSF sync feature. The driver periodically + * fetches TSF and host time mapping from the firmware with interval configured + * through the %QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL attribute. If the + * interval value is not provided the driver will use the default value. The + * userspace can query the TSF and host time mapping via the %QCA_TSF_GET + * command. + * @QCA_TSF_SYNC_STOP: Stop periodic TSF sync feature. + */ +enum qca_tsf_cmd { + QCA_TSF_CAPTURE, + QCA_TSF_GET, + QCA_TSF_SYNC_GET, + QCA_TSF_AUTO_REPORT_ENABLE, + QCA_TSF_AUTO_REPORT_DISABLE, + QCA_TSF_SYNC_START, + QCA_TSF_SYNC_STOP, +}; + +/** + * enum qca_vendor_attr_wisa_cmd + * @QCA_WLAN_VENDOR_ATTR_WISA_MODE: WISA mode value (u32) + * WISA setup vendor commands + */ +enum qca_vendor_attr_wisa_cmd { + QCA_WLAN_VENDOR_ATTR_WISA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WISA_MODE, + QCA_WLAN_VENDOR_ATTR_WISA_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WISA_MAX = + QCA_WLAN_VENDOR_ATTR_WISA_AFTER_LAST - 1 +}; + +/* IEEE 802.11 Vendor Specific elements */ + +/** + * enum qca_vendor_element_id - QCA Vendor Specific element types + * + * These values are used to identify QCA Vendor Specific elements. The + * payload of the element starts with the three octet OUI (OUI_QCA) and + * is followed by a single octet type which is defined by this enum. + * + * @QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST: P2P preferred channel list. + * This element can be used to specify preference order for supported + * channels. The channels in this list are in preference order (the first + * one has the highest preference) and are described as a pair of + * (global) Operating Class and Channel Number (each one octet) fields. + * + * This extends the standard P2P functionality by providing option to have + * more than one preferred operating channel. When this element is present, + * it replaces the preference indicated in the Operating Channel attribute. + * For supporting other implementations, the Operating Channel attribute is + * expected to be used with the highest preference channel. Similarly, all + * the channels included in this Preferred channel list element are + * expected to be included in the Channel List attribute. + * + * This vendor element may be included in GO Negotiation Request, P2P + * Invitation Request, and Provision Discovery Request frames. + * + * @QCA_VENDOR_ELEM_HE_CAPAB: HE Capabilities element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID. The payload of this + * vendor specific element is defined by the latest P802.11ax draft. + * Please note that the draft is still work in progress and this element + * payload is subject to change. + * + * @QCA_VENDOR_ELEM_HE_OPER: HE Operation element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID. The payload of this + * vendor specific element is defined by the latest P802.11ax draft. + * Please note that the draft is still work in progress and this element + * payload is subject to change. + * + * @QCA_VENDOR_ELEM_RAPS: RAPS element (OFDMA-based Random Access Parameter Set + * element). + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_MU_EDCA_PARAMS: MU EDCA Parameter Set element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_BSS_COLOR_CHANGE: BSS Color Change Announcement element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_ALLPLAY: Allplay element + */ +enum qca_vendor_element_id { + QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST = 0, + QCA_VENDOR_ELEM_HE_CAPAB = 1, + QCA_VENDOR_ELEM_HE_OPER = 2, + QCA_VENDOR_ELEM_RAPS = 3, + QCA_VENDOR_ELEM_MU_EDCA_PARAMS = 4, + QCA_VENDOR_ELEM_BSS_COLOR_CHANGE = 5, + QCA_VENDOR_ELEM_ALLPLAY = 6, +}; + +/** + * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the + * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take. + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority + */ +enum qca_wlan_vendor_scan_priority { + QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0, + QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1, + QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2, + QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3, + QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4, +}; + +/** + * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes + * + * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan + * @QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES: Nested unsigned 32-bit attributes + * with frequencies to be scanned (in MHz) + * @QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS: Nested attribute with SSIDs to be scanned + * @QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES: Nested array attribute of supported + * rates to be included + * @QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE: flag used to send probe requests + * at non CCK rate in 2GHz band + * @QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS: Unsigned 32-bit scan flags + * @QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE: Unsigned 64-bit cookie provided by the + * driver for the specific scan request + * @QCA_WLAN_VENDOR_ATTR_SCAN_STATUS: Unsigned 8-bit status of the scan + * request decoded as in enum scan_status + * @QCA_WLAN_VENDOR_ATTR_SCAN_MAC: 6-byte MAC address to use when randomisation + * scan flag is set + * @QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK: 6-byte MAC address mask to be used with + * randomisation + * @QCA_WLAN_VENDOR_ATTR_SCAN_BSSID: 6-byte MAC address representing the + * specific BSSID to scan for. + * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in + * microseconds. This is a common value which applies across all + * frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES. + * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to + * other scan requests. It is a u32 attribute and takes values from enum + * qca_wlan_vendor_scan_priority. This is an optional attribute. + * If this attribute is not configured, the driver shall use + * QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan. + */ +enum qca_wlan_vendor_attr_scan { + QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0, + QCA_WLAN_VENDOR_ATTR_SCAN_IE = 1, + QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES = 2, + QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS = 3, + QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES = 4, + QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE = 5, + QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS = 6, + QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE = 7, + QCA_WLAN_VENDOR_ATTR_SCAN_STATUS = 8, + QCA_WLAN_VENDOR_ATTR_SCAN_MAC = 9, + QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10, + QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11, + QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12, + QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13, + QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SCAN_MAX = + QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1 +}; + +/** + * enum scan_status - Specifies the valid values the vendor scan attribute + * QCA_WLAN_VENDOR_ATTR_SCAN_STATUS can take + * + * @VENDOR_SCAN_STATUS_NEW_RESULTS: implies the vendor scan is successful with + * new scan results + * @VENDOR_SCAN_STATUS_ABORTED: implies the vendor scan was aborted in-between + */ +enum scan_status { + VENDOR_SCAN_STATUS_NEW_RESULTS, + VENDOR_SCAN_STATUS_ABORTED, + VENDOR_SCAN_STATUS_MAX, +}; + +/** + * enum qca_vendor_attr_ota_test - Specifies the values for vendor + * command QCA_NL80211_VENDOR_SUBCMD_OTA_TEST + * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE: enable ota test + */ +enum qca_vendor_attr_ota_test { + QCA_WLAN_VENDOR_ATTR_OTA_TEST_INVALID, + /* 8-bit unsigned value to indicate if OTA test is enabled */ + QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX = + QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_attr_txpower_scale - vendor sub commands index + * + * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE: scaling value + */ +enum qca_vendor_attr_txpower_scale { + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_INVALID, + /* 8-bit unsigned value to indicate the scaling of tx power */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX = + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_attr_txpower_decr_db - Attributes for TX power decrease + * + * These attributes are used with QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_DECR_DB. + */ +enum qca_vendor_attr_txpower_decr_db { + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_INVALID, + /* 8-bit unsigned value to indicate the reduction of TX power in dB for + * a virtual interface. + */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_MAX = + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_AFTER_LAST - 1 +}; + +/* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and + * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION subcommands. + */ +enum qca_wlan_vendor_attr_config { + QCA_WLAN_VENDOR_ATTR_CONFIG_INVALID = 0, + /* Unsigned 32-bit value to set the DTIM period. + * Whether the wifi chipset wakes at every dtim beacon or a multiple of + * the DTIM period. If DTIM is set to 3, the STA shall wake up every 3 + * DTIM beacons. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM = 1, + /* Unsigned 32-bit value to set the wifi_iface stats averaging factor + * used to calculate statistics like average the TSF offset or average + * number of frame leaked. + * For instance, upon Beacon frame reception: + * current_avg = ((beacon_TSF - TBTT) * factor + previous_avg * (0x10000 - factor) ) / 0x10000 + * For instance, when evaluating leaky APs: + * current_avg = ((num frame received within guard time) * factor + previous_avg * (0x10000 - factor)) / 0x10000 + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR = 2, + /* Unsigned 32-bit value to configure guard time, i.e., when + * implementing IEEE power management based on frame control PM bit, how + * long the driver waits before shutting down the radio and after + * receiving an ACK frame for a Data frame with PM bit set. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME = 3, + /* Unsigned 32-bit value to change the FTM capability dynamically */ + QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT = 4, + /* Unsigned 16-bit value to configure maximum TX rate dynamically */ + QCA_WLAN_VENDOR_ATTR_CONF_TX_RATE = 5, + /* Unsigned 32-bit value to configure the number of continuous + * Beacon Miss which shall be used by the firmware to penalize + * the RSSI. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS = 6, + /* Unsigned 8-bit value to configure the channel avoidance indication + * behavior. Firmware to send only one indication and ignore duplicate + * indications when set to avoid multiple Apps wakeups. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND = 7, + /* 8-bit unsigned value to configure the maximum TX MPDU for + * aggregation. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION = 8, + /* 8-bit unsigned value to configure the maximum RX MPDU for + * aggregation. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION = 9, + /* 8-bit unsigned value to configure the Non aggregrate/11g sw + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY = 10, + /* 8-bit unsigned value to configure the aggregrate sw + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY = 11, + /* 8-bit unsigned value to configure the MGMT frame + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY = 12, + /* 8-bit unsigned value to configure the CTRL frame + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY = 13, + /* 8-bit unsigned value to configure the propagation delay for + * 2G/5G band (0~63, units in us) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY = 14, + /* Unsigned 32-bit value to configure the number of unicast TX fail + * packet count. The peer is disconnected once this threshold is + * reached. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT = 15, + /* Attribute used to set scan default IEs to the driver. + * + * These IEs can be used by scan operations that will be initiated by + * the driver/firmware. + * + * For further scan requests coming to the driver, these IEs should be + * merged with the IEs received along with scan request coming to the + * driver. If a particular IE is present in the scan default IEs but not + * present in the scan request, then that IE should be added to the IEs + * sent in the Probe Request frames for that scan request. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES = 16, + /* Unsigned 32-bit attribute for generic commands */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_COMMAND = 17, + /* Unsigned 32-bit value attribute for generic commands */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_VALUE = 18, + /* Unsigned 32-bit data attribute for generic command response */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA = 19, + /* Unsigned 32-bit length attribute for + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_LENGTH = 20, + /* Unsigned 32-bit flags attribute for + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_FLAGS = 21, + /* Unsigned 32-bit, defining the access policy. + * See enum qca_access_policy. Used with + * QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY = 22, + /* Sets the list of full set of IEs for which a specific access policy + * has to be applied. Used along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY to control the access. + * Zero length payload can be used to clear this access constraint. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST = 23, + /* Unsigned 32-bit, specifies the interface index (netdev) for which the + * corresponding configurations are applied. If the interface index is + * not specified, the configurations are attributed to the respective + * wiphy. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX = 24, + /* 8-bit unsigned value to trigger QPower: 1-Enable, 0-Disable */ + QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER = 25, + /* 8-bit unsigned value to configure the driver and below layers to + * ignore the assoc disallowed set by APs while connecting + * 1-Ignore, 0-Don't ignore + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED = 26, + /* 32-bit unsigned value to trigger antenna diversity features: + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA = 27, + /* 32-bit unsigned value to configure specific chain antenna */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN = 28, + /* 32-bit unsigned value to trigger cycle selftest + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST = 29, + /* 32-bit unsigned to configure the cycle time of selftest + * the unit is micro-second + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL = 30, + /* 32-bit unsigned value to set reorder timeout for AC_VO */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE = 31, + /* 32-bit unsigned value to set reorder timeout for AC_VI */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO = 32, + /* 32-bit unsigned value to set reorder timeout for AC_BE */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT = 33, + /* 32-bit unsigned value to set reorder timeout for AC_BK */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND = 34, + /* 6-byte MAC address to point out the specific peer */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC = 35, + /* 32-bit unsigned value to set window size for specific peer */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT = 36, + /* 8-bit unsigned value to set the beacon miss threshold in 2.4 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24 = 37, + /* 8-bit unsigned value to set the beacon miss threshold in 5 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5 = 38, + /* 32-bit unsigned value to configure 5 or 10 MHz channel width for + * station device while in disconnect state. The attribute use the + * value of enum nl80211_chan_width: NL80211_CHAN_WIDTH_5 means 5 MHz, + * NL80211_CHAN_WIDTH_10 means 10 MHz. If set, the device work in 5 or + * 10 MHz channel width, the station will not connect to a BSS using 20 + * MHz or higher bandwidth. Set to NL80211_CHAN_WIDTH_20_NOHT to + * clear this constraint. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH = 39, + /* 32-bit unsigned value to configure the propagation absolute delay + * for 2G/5G band (units in us) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY = 40, + /* 32-bit unsigned value to set probe period */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD = 41, + /* 32-bit unsigned value to set stay period */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD = 42, + /* 32-bit unsigned value to set snr diff */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF = 43, + /* 32-bit unsigned value to set probe dwell time */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME = 44, + /* 32-bit unsigned value to set mgmt snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT = 45, + /* 32-bit unsigned value to set data snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT = 46, + /* 32-bit unsigned value to set ack snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT = 47, + /* 32-bit unsigned value to configure the listen interval. + * This is in units of beacon intervals. This configuration alters + * the negotiated listen interval with the AP during the connection. + * It is highly recommended to configure a value less than or equal to + * the one negotiated during the association. Configuring any greater + * value can have adverse effects (frame loss, AP disassociating STA, + * etc.). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL = 48, + /* + * 8 bit unsigned value that is set on an AP/GO virtual interface to + * disable operations that would cause the AP/GO to leave its operating + * channel. + * + * This will restrict the scans to the AP/GO operating channel and the + * channels of the other band, if DBS is supported.A STA/CLI interface + * brought up after this setting is enabled, will be restricted to + * connecting to devices only on the AP/GO interface's operating channel + * or on the other band in DBS case. P2P supported channel list is + * modified, to only include AP interface's operating-channel and the + * channels of the other band if DBS is supported. + * + * These restrictions are only applicable as long as the AP/GO interface + * is alive. If the AP/GO interface is brought down then this + * setting/restriction is forgotten. + * + * If this variable is set on an AP/GO interface while a multi-channel + * concurrent session is active, it has no effect on the operation of + * the current interfaces, other than restricting the scan to the AP/GO + * operating channel and the other band channels if DBS is supported. + * However, if the STA is brought down and restarted then the new STA + * connection will either be formed on the AP/GO channel or on the + * other band in a DBS case. This is because of the scan being + * restricted on these channels as mentioned above. + * + * 1-Restrict / 0-Don't restrict offchannel operations. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL = 49, + /* + * 8 bit unsigned value to enable/disable LRO (Large Receive Offload) + * on an interface. + * 1 - Enable, 0 - Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LRO = 50, + + /* + * 8 bit unsigned value to globally enable/disable scan + * 1 - Enable, 0 - Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE = 51, + + /* 8-bit unsigned value to set the total beacon miss count + * This parameter will set the total beacon miss count. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT = 52, + + /* Unsigned 32-bit value to configure the number of continuous + * Beacon Miss which shall be used by the firmware to penalize + * the RSSI for BTC. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS_BTC = 53, + + /* 8-bit unsigned value to configure the driver and below layers to + * enable/disable all FILS features. + * 0-enable, 1-disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS = 54, + + /* 16-bit unsigned value to configure the level of WLAN latency + * module. See enum qca_wlan_vendor_attr_config_latency_level. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL = 55, + + /* 8-bit unsigned value indicating the driver to use the RSNE as-is from + * the connect interface. Exclusively used for the scenarios where the + * device is used as a test bed device with special functionality and + * not recommended for production. This helps driver to not validate the + * RSNE passed from user space and thus allow arbitrary IE data to be + * used for testing purposes. + * 1-enable, 0-disable. + * Applications set/reset this configuration. If not reset, this + * parameter remains in use until the driver is unloaded. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE = 56, + + /* 8-bit unsigned value to trigger green Tx power saving. + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GTX = 57, + + /* Attribute to configure disconnect IEs to the driver. + * This carries an array of unsigned 8-bit characters. + * + * If this is configured, driver shall fill the IEs in disassoc/deauth + * frame. + * These IEs are expected to be considered only for the next + * immediate disconnection (disassoc/deauth frame) originated by + * the DUT, irrespective of the entity (user space/driver/firmware) + * triggering the disconnection. + * The host drivers are not expected to use the IEs set through + * this interface for further disconnections after the first immediate + * disconnection initiated post the configuration. + * If the IEs are also updated through cfg80211 interface (after the + * enhancement to cfg80211_disconnect), host driver is expected to + * take the union of IEs from both of these interfaces and send in + * further disassoc/deauth frames. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES = 58, + + /* 8-bit unsigned value for ELNA bypass. + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS = 59, + + /* 8-bit unsigned value. This attribute enables/disables the host driver + * to send the Beacon Report Response with failure reason for the + * scenarios where STA cannot honor the Beacon Report Request from AP. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL = 60, + + /* 8-bit unsigned value. This attribute enables/disables the host driver + * to send roam reason information in the Reassociation Request frame to + * the target AP when roaming within the same ESS. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON = 61, + + /* 32-bit unsigned value to configure different PHY modes to the + * driver/firmware. The possible values are defined in + * enum qca_wlan_vendor_phy_mode. The configuration will be reset to + * default value, i.e., QCA_WLAN_VENDOR_PHY_MODE_AUTO upon restarting + * the driver. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE = 62, + + /* 8-bit unsigned value to configure the maximum supported channel width + * for STA mode. If this value is configured when STA is in connected + * state, it should not exceed the negotiated channel width. If it is + * configured when STA is in disconnected state, the configured value + * will take effect for the next immediate connection. + * Possible values are: + * NL80211_CHAN_WIDTH_20 + * NL80211_CHAN_WIDTH_40 + * NL80211_CHAN_WIDTH_80 + * NL80211_CHAN_WIDTH_80P80 + * NL80211_CHAN_WIDTH_160 + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH = 63, + + /* 8-bit unsigned value to enable/disable dynamic bandwidth adjustment. + * This attribute is only applicable for STA mode. When dynamic + * bandwidth adjustment is disabled, STA will use static channel width + * the value of which is negotiated during connection. + * 1-enable (default), 0-disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW = 64, + + /* 8-bit unsigned value to configure the maximum number of subframes of + * TX MSDU for aggregation. Possible values are 0-31. When set to 0, + * it is decided by the hardware. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION = 65, + + /* 8-bit unsigned value to configure the maximum number of subframes of + * RX MSDU for aggregation. Possible values are 0-31. When set to 0, + * it is decided by the hardware. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION = 66, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the LDPC capability of the device. When configured in + * the disconnected state, the updated configuration will be considered + * for the immediately following connection attempt. If this + * configuration is modified while the device is in the connected state, + * the LDPC TX will be updated with this configuration immediately, + * while the LDPC RX configuration update will take place starting from + * the subsequent association attempt. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC = 67, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the TX STBC capability of the device. When configured + * in the disconnected state, the updated configuration will be + * considered for the immediately following connection attempt. If the + * connection is formed with TX STBC enabled and if this configuration + * is disabled during that association, the TX will be impacted + * immediately. Further connection attempts will disable TX STBC. + * However, enabling the TX STBC for a connected session with disabled + * capability is not allowed and will fail. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC = 68, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the RX STBC capability of the device. When configured + * in the disconnected state, the updated configuration will be + * considered for the immediately following connection attempt. If the + * configuration is modified in the connected state, there will be no + * impact for the current association, but further connection attempts + * will use the updated configuration. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC = 69, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams. When configured in the disconnected + * state, the updated configuration will be considered for the + * immediately following connection attempt. If the NSS is updated after + * the connection, the updated NSS value is notified to the peer using + * the Operating Mode Notification/Spatial Multiplexing Power Save + * frame. The updated NSS value after the connection shall not be + * greater than the one negotiated during the connection. Any such + * higher value configuration shall be returned with a failure. + * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done + * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and + * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to + * configure the asymmetric NSS configuration (such as 1X2). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70, + /* 8-bit unsigned value to trigger Optimized Power Management: + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT = 71, + + /* 8-bit unsigned value. This attribute takes the QoS/access category + * value represented by the enum qca_wlan_ac_type and expects the driver + * to upgrade the UDP frames to this access category. The value of + * QCA_WLAN_AC_ALL is invalid for this attribute. This will override the + * DSCP value configured in the frame with the intention to only upgrade + * the access category. That said, it is not intended to downgrade the + * access category for the frames. + * Set the value to QCA_WLAN_AC_BK if the QoS upgrade needs to be + * disabled, as BK is of the lowest priority and an upgrade to it does + * not result in any changes for the frames. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE = 72, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for transmitting data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_TX_CHAINS = 73, + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for receiving data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS = 74, + + /* 8-bit unsigned value to configure ANI setting type. + * See &enum qca_wlan_ani_setting for possible values. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_SETTING = 75, + /* 32-bit signed value to configure ANI level. This is used when + * ANI settings type is &QCA_WLAN_ANI_SETTING_FIXED. + * The set and get of ANI level with &QCA_WLAN_ANI_SETTING_AUTO + * is invalid, the driver will return a failure. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for transmitting the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The TX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver + * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for receiving the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The RX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver + * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78, + + /* + * 8-bit unsigned value. This attribute, when set, indicates whether the + * specified interface is the primary STA interface when there are more + * than one STA interfaces concurrently active. + * + * This configuration helps the firmware/hardware to support certain + * features (e.g., roaming) on this primary interface, if the same + * cannot be supported on the concurrent STA interfaces simultaneously. + * + * This configuration is only applicable for a single STA interface on + * a device and gives the priority for it only over other concurrent STA + * interfaces. + * + * If the device is a multi wiphy/soc, this configuration applies to a + * single STA interface across the wiphys. + * + * 1-Enable (is the primary STA), 0-Disable (is not the primary STA) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79, + + /* + * 8-bit unsigned value. This attribute can be used to configure the + * driver to enable/disable FT-over-DS feature. Possible values for + * this attribute are 1-Enable and 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80, + + /* + * 8-bit unsigned value. This attribute can be used to configure the + * firmware to enable/disable ARP/NS offload feature. Possible values + * for this attribute are 0-Disable and 1-Enable. + * + * This attribute is only applicable for STA/P2P-Client interface, + * and is optional, default behavior is ARP/NS offload enabled. + * + * This attribute can be set in disconnected and connected state, and + * will restore to the default behavior if the interface is closed. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1, +}; + +/* Compatibility defines for previously used incorrect enum + * qca_wlan_vendor_attr_config names. These values should not be used in any + * new implementation. */ +#define QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES \ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES +#define QCA_WLAN_VENDOR_ATTR_BEACON_REPORT_FAIL \ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL + +/** + * enum qca_wlan_ani_setting - ANI setting type + * @QCA_WLAN_ANI_SETTING_AUTO: Automatically determine ANI level + * @QCA_WLAN_ANI_SETTING_FIXED: Fix ANI level to the dBm parameter + */ +enum qca_wlan_ani_setting { + QCA_WLAN_ANI_SETTING_AUTO = 0, + QCA_WLAN_ANI_SETTING_FIXED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_sap_config - Parameters for AP configuration + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL: Optional (u8) + * Channel number on which Access Point should restart. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY: Optional (u32) + * Channel center frequency (MHz) on which the access point should restart. + */ +enum qca_wlan_vendor_attr_sap_config { + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL = 1, + + /* List of frequencies on which AP is expected to operate. + * This is irrespective of ACS configuration. This list is a priority + * based one and is looked for before the AP is created to ensure the + * best concurrency sessions (avoid MCC and use DBS/SCC) co-exist in + * the system. + */ + QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST = 2, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY = 3, + + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_sap_conditional_chan_switch - Parameters for AP + * conditional channel switch + */ +enum qca_wlan_vendor_attr_sap_conditional_chan_switch { + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_INVALID = 0, + /* Priority based frequency list (an array of u32 values in host byte + * order) + */ + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST = 1, + /* Status of the conditional switch (u32). + * 0: Success, Non-zero: Failure + */ + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS = 2, + + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX = + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_gpio_attr - Parameters for GPIO configuration + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND: Required (u32) + * value to specify the GPIO command. Please refer to enum qca_gpio_cmd_type + * for the available values. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM: Required (u32) + * value to specify the GPIO number. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG or %QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE: Required (u32) + * value to specify the GPIO output level. Please refer to enum qca_gpio_value + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32) + * value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32) + * value to specify the GPIO interrupt mode. Please refer to enum + * qca_gpio_interrupt_mode for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32) + * value to specify the GPIO direction. Please refer to enum qca_gpio_direction + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32) + * Value to specify the mux config. Meaning of a given value is dependent + * on the target chipset and GPIO pin. Must be of the range 0-15. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32) + * Value to specify the drive, refer to enum qca_gpio_drive. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0). + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag) + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all + * other parameters for the given GPIO will be obtained from internal + * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be + * specified to indicate the GPIO pin being configured. + */ +enum qca_wlan_gpio_attr { + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0, + /* Unsigned 32-bit attribute for GPIO command */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND = 1, + /* Unsigned 32-bit attribute for GPIO PIN number to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM = 2, + /* Unsigned 32-bit attribute for GPIO value to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE = 3, + /* Unsigned 32-bit attribute for GPIO pull type */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE = 4, + /* Unsigned 32-bit attribute for GPIO interrupt mode */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5, + /* Unsigned 32-bit attribute for GPIO direction to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6, + /* Unsigned 32-bit attribute for GPIO mux config */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7, + /* Unsigned 32-bit attribute for GPIO drive */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8, + /* Flag attribute for using internal GPIO configuration */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST - 1 +}; + +/** + * enum gpio_cmd_type - GPIO configuration command type + * @QCA_WLAN_VENDOR_GPIO_CONFIG: Set GPIO configuration info + * @QCA_WLAN_VENDOR_GPIO_OUTPUT: Set GPIO output level + */ +enum qca_gpio_cmd_type { + QCA_WLAN_VENDOR_GPIO_CONFIG = 0, + QCA_WLAN_VENDOR_GPIO_OUTPUT = 1, +}; + +/** + * enum qca_gpio_pull_type - GPIO pull type + * @QCA_WLAN_GPIO_PULL_NONE: Set GPIO pull type to none + * @QCA_WLAN_GPIO_PULL_UP: Set GPIO pull up + * @QCA_WLAN_GPIO_PULL_DOWN: Set GPIO pull down + */ +enum qca_gpio_pull_type { + QCA_WLAN_GPIO_PULL_NONE = 0, + QCA_WLAN_GPIO_PULL_UP = 1, + QCA_WLAN_GPIO_PULL_DOWN = 2, + QCA_WLAN_GPIO_PULL_MAX, +}; + +/** + * enum qca_gpio_direction - GPIO direction + * @QCA_WLAN_GPIO_INPUT: Set GPIO as input mode + * @QCA_WLAN_GPIO_OUTPUT: Set GPIO as output mode + * @QCA_WLAN_GPIO_VALUE_MAX: Invalid value + */ +enum qca_gpio_direction { + QCA_WLAN_GPIO_INPUT = 0, + QCA_WLAN_GPIO_OUTPUT = 1, + QCA_WLAN_GPIO_DIR_MAX, +}; + +/** + * enum qca_gpio_value - GPIO Value + * @QCA_WLAN_GPIO_LEVEL_LOW: set gpio output level to low + * @QCA_WLAN_GPIO_LEVEL_HIGH: set gpio output level to high + * @QCA_WLAN_GPIO_LEVEL_MAX: Invalid value + */ +enum qca_gpio_value { + QCA_WLAN_GPIO_LEVEL_LOW = 0, + QCA_WLAN_GPIO_LEVEL_HIGH = 1, + QCA_WLAN_GPIO_LEVEL_MAX, +}; + +/** + * enum gpio_interrupt_mode - GPIO interrupt mode + * @QCA_WLAN_GPIO_INTMODE_DISABLE: Disable interrupt trigger + * @QCA_WLAN_GPIO_INTMODE_RISING_EDGE: Interrupt with GPIO rising edge trigger + * @QCA_WLAN_GPIO_INTMODE_FALLING_EDGE: Interrupt with GPIO falling edge trigger + * @QCA_WLAN_GPIO_INTMODE_BOTH_EDGE: Interrupt with GPIO both edge trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_LOW: Interrupt with GPIO level low trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH: Interrupt with GPIO level high trigger + * @QCA_WLAN_GPIO_INTMODE_MAX: Invalid value + */ +enum qca_gpio_interrupt_mode { + QCA_WLAN_GPIO_INTMODE_DISABLE = 0, + QCA_WLAN_GPIO_INTMODE_RISING_EDGE = 1, + QCA_WLAN_GPIO_INTMODE_FALLING_EDGE = 2, + QCA_WLAN_GPIO_INTMODE_BOTH_EDGE = 3, + QCA_WLAN_GPIO_INTMODE_LEVEL_LOW = 4, + QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH = 5, + QCA_WLAN_GPIO_INTMODE_MAX, +}; + +/** + * enum qca_gpio_drive - GPIO drive + * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA + * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA + * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA + * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA + * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA + * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA + * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA + * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA + * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive + */ +enum qca_gpio_drive { + QCA_WLAN_GPIO_DRIVE_2MA = 0, + QCA_WLAN_GPIO_DRIVE_4MA = 1, + QCA_WLAN_GPIO_DRIVE_6MA = 2, + QCA_WLAN_GPIO_DRIVE_8MA = 3, + QCA_WLAN_GPIO_DRIVE_10MA = 4, + QCA_WLAN_GPIO_DRIVE_12MA = 5, + QCA_WLAN_GPIO_DRIVE_14MA = 6, + QCA_WLAN_GPIO_DRIVE_16MA = 7, + QCA_WLAN_GPIO_DRIVE_MAX, +}; + +/** + * qca_wlan_set_qdepth_thresh_attr - Parameters for setting + * MSDUQ depth threshold per peer per tid in the target + * + * Associated Vendor Command: + * QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH + */ +enum qca_wlan_set_qdepth_thresh_attr { + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_INVALID = 0, + /* 6-byte MAC address */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_MAC_ADDR, + /* Unsigned 32-bit attribute for holding the TID */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_TID, + /* Unsigned 32-bit attribute for holding the update mask + * bit 0 - Update high priority msdu qdepth threshold + * bit 1 - Update low priority msdu qdepth threshold + * bit 2 - Update UDP msdu qdepth threshold + * bit 3 - Update Non UDP msdu qdepth threshold + * rest of bits are reserved + */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_UPDATE_MASK, + /* Unsigned 32-bit attribute for holding the threshold value */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_VALUE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_LAST, + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_MAX = + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_LAST - 1, +}; + +/** + * enum qca_acs_dfs_mode - Defines different types of DFS channel + * configurations for ACS operation. + * + * @QCA_ACS_DFS_MODE_NONE: Refer to invalid DFS mode + * @QCA_ACS_DFS_MODE_ENABLE: Consider DFS channels in ACS operation + * @QCA_ACS_DFS_MODE_DISABLE: Do not consider DFS channels in ACS operation + * @QCA_ACS_DFS_MODE_DEPRIORITIZE: Deprioritize DFS channels in ACS operation + */ +enum qca_acs_dfs_mode { + QCA_ACS_DFS_MODE_NONE = 0, + QCA_ACS_DFS_MODE_ENABLE = 1, + QCA_ACS_DFS_MODE_DISABLE = 2, + QCA_ACS_DFS_MODE_DEPRIORITIZE = 3, +}; + +/** + * enum qca_wlan_vendor_attr_acs_config - Defines Configuration attributes + * used by the vendor command QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE: Required (u8) + * DFS mode for ACS operation from enum qca_acs_dfs_mode. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT: Required (u8) + * channel number hint for ACS operation, if valid channel is specified then + * ACS operation gives priority to this channel. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT: Required (u32). + * Channel center frequency (MHz) hint for ACS operation, if a valid center + * frequency is specified, ACS operation gives priority to this channel. + */ +enum qca_wlan_vendor_attr_acs_config { + QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE = 1, + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT = 2, + QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT = 3, + + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX = + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_hw_capability - Wi-Fi hardware capability + */ +enum qca_wlan_vendor_attr_get_hw_capability { + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_INVALID, + /* Antenna isolation + * An attribute used in the response. + * The content of this attribute is encoded in a byte array. Each byte + * value is an antenna isolation value. The array length is the number + * of antennas. + */ + QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + /* Request HW capability + * An attribute used in the request. + * The content of this attribute is a u32 array for one or more of + * hardware capabilities (attribute IDs) that are being requested. Each + * u32 value has a value from this + * enum qca_wlan_vendor_attr_get_hw_capability + * identifying which capabilities are requested. + */ + QCA_WLAN_VENDOR_ATTR_GET_HW_CAPABILITY, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_MAX = + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ll_stats_ext - Attributes for MAC layer monitoring + * offload which is an extension for LL_STATS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD: Monitoring period. Unit in ms. + * If MAC counters do not exceed the threshold, FW will report monitored + * link layer counters periodically as this setting. The first report is + * always triggered by this timer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD: It is a percentage (1-99). + * For each MAC layer counter, FW holds two copies. One is the current value. + * The other is the last report. Once a current counter's increment is larger + * than the threshold, FW will indicate that counter to host even if the + * monitoring timer does not expire. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG: Peer STA power state change + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID: TID of MSDU + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU: Count of MSDU with the same + * failure code. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS: TX failure code + * 1: TX packet discarded + * 2: No ACK + * 3: Postpone + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS: peer MAC address + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE: Peer STA current state + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL: Global threshold. + * Threshold for all monitored parameters. If per counter dedicated threshold + * is not enabled, this threshold will take effect. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE: Indicate what triggers this + * event, PERORID_TIMEOUT == 1, THRESH_EXCEED == 0. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID: interface ID + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID: peer ID + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP: bitmap for TX counters + * Bit0: TX counter unit in MSDU + * Bit1: TX counter unit in MPDU + * Bit2: TX counter unit in PPDU + * Bit3: TX counter unit in byte + * Bit4: Dropped MSDUs + * Bit5: Dropped Bytes + * Bit6: MPDU retry counter + * Bit7: MPDU failure counter + * Bit8: PPDU failure counter + * Bit9: MPDU aggregation counter + * Bit10: MCS counter for ACKed MPDUs + * Bit11: MCS counter for Failed MPDUs + * Bit12: TX Delay counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP: bitmap for RX counters + * Bit0: MAC RX counter unit in MPDU + * Bit1: MAC RX counter unit in byte + * Bit2: PHY RX counter unit in PPDU + * Bit3: PHY RX counter unit in byte + * Bit4: Disorder counter + * Bit5: Retry counter + * Bit6: Duplication counter + * Bit7: Discard counter + * Bit8: MPDU aggregation size counter + * Bit9: MCS counter + * Bit10: Peer STA power state change (wake to sleep) counter + * Bit11: Peer STA power save counter, total time in PS mode + * Bit12: Probe request counter + * Bit13: Other management frames counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP: bitmap for CCA + * Bit0: Idle time + * Bit1: TX time + * Bit2: time RX in current bss + * Bit3: Out of current bss time + * Bit4: Wireless medium busy time + * Bit5: RX in bad condition time + * Bit6: TX in bad condition time + * Bit7: time wlan card not available + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP: bitmap for signal + * Bit0: Per channel SNR counter + * Bit1: Per channel noise floor counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM: number of peers + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM: number of channels + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_AC_RX_NUM: number of RX stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS: per channel BSS CCA stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER: container for per PEER stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU: Number of total TX MSDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU: Number of total TX MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU: Number of total TX PPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES: bytes of TX data + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP: Number of dropped TX packets + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES: Bytes dropped + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY: waiting time without an ACK + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK: number of MPDU not-ACKed + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK: number of PPDU not-ACKed + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM: + * aggregation stats buffer length + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM: length of mcs stats + * buffer for ACKed MPDUs. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM: length of mcs stats + * buffer for failed MPDUs. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE: + * length of delay stats array. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR: TX aggregation stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS: MCS stats for ACKed MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS: MCS stats for failed MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY: tx delay stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU: MPDUs received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES: bytes received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU: PPDU received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES: PPDU bytes received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST: packets lost + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY: number of RX packets + * flagged as retransmissions + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP: number of RX packets + * flagged as duplicated + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD: number of RX + * packets discarded + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM: length of RX aggregation + * stats buffer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM: length of RX mcs + * stats buffer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS: RX mcs stats buffer + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR: aggregation stats buffer + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES: times STAs go to sleep + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION: STAs' total sleep time + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ: number of probe + * requests received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT: number of other mgmt + * frames received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME: Percentage of idle time + * there is no TX, nor RX, nor interference. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME: percentage of time + * transmitting packets. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_TIME: percentage of time + * for receiving. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY: percentage of time + * interference detected. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD: percentage of time + * receiving packets with errors. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD: percentage of time + * TX no-ACK. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL: percentage of time + * the chip is unable to work in normal conditions. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME: percentage of time + * receiving packets in current BSS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME: percentage of time + * receiving packets not in current BSS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM: number of antennas + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL: + * This is a container for per antenna signal stats. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR: per antenna SNR value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF: per antenna NF value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_RSSI_BEACON: RSSI of beacon + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_SNR_BEACON: SNR of beacon + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_REPORT_TIME: u64 + * Absolute timestamp from 1970/1/1, unit in ms. After receiving the + * message, user layer APP could call gettimeofday to get another + * timestamp and calculate transfer delay for the message. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MEASUREMENT_TIME: u32 + * Real period for this measurement, unit in us. + */ +enum qca_wlan_vendor_attr_ll_stats_ext { + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_INVALID = 0, + + /* Attributes for configurations */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD, + + /* Peer STA power state change */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG, + + /* TX failure event */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS, + + /* MAC counters */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER, + + /* Sub-attributes for PEER_AC_TX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY, + + /* Sub-attributes for PEER_AC_RX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT, + + /* Sub-attributes for CCA_BSS */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL, + + /* sub-attribute for BSS_RX_TIME */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME, + + /* Sub-attributes for PEER_SIGNAL */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF, + + /* Sub-attributes for IFACE_BSS */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_RSSI_BEACON, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_SNR_BEACON, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_REPORT_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MEASUREMENT_TIME, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST - 1 +}; + +/* Attributes for FTM commands and events */ + +/** + * enum qca_wlan_vendor_attr_loc_capa - Indoor location capabilities + * + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS: Various flags. See + * enum qca_wlan_vendor_attr_loc_capa_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS: Maximum number + * of measurement sessions that can run concurrently. + * Default is one session (no session concurrency). + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS: The total number of unique + * peers that are supported in running sessions. For example, + * if the value is 8 and maximum number of sessions is 2, you can + * have one session with 8 unique peers, or 2 sessions with 4 unique + * peers each, and so on. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP: Maximum number + * of bursts per peer, as an exponent (2^value). Default is 0, + * meaning no multi-burst support. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST: Maximum number + * of measurement exchanges allowed in a single burst. + * @QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES: Supported AOA measurement + * types. A bit mask (unsigned 32 bit value), each bit corresponds + * to an AOA type as defined by enum qca_vendor_attr_aoa_type. + */ +enum qca_wlan_vendor_attr_loc_capa { + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_INVALID, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST, + QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_MAX = + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_loc_capa_flags: Indoor location capability flags + * + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER: Set if driver + * can be configured as an FTM responder (for example, an AP that + * services FTM requests). QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * will be supported if set. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR: Set if driver + * can run FTM sessions. QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION + * will be supported if set. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP: Set if FTM responder + * supports immediate (ASAP) response. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA: Set if driver supports standalone + * AOA measurement using QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM: Set if driver supports + * requesting AOA measurements as part of an FTM session. + */ +enum qca_wlan_vendor_attr_loc_capa_flags { + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER = 1 << 0, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR = 1 << 1, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP = 1 << 2, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA = 1 << 3, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM = 1 << 4, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_info: Information about + * a single peer in a measurement session. + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR: The MAC address of the peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS: Various flags related + * to measurement. See enum qca_wlan_vendor_attr_ftm_peer_meas_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS: Nested attribute of + * FTM measurement parameters, as specified by IEEE P802.11-REVmc/D7.0 + * 9.4.2.167. See enum qca_wlan_vendor_attr_ftm_meas_param for + * list of supported attributes. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID: Initial token ID for + * secure measurement. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA + * measurement every <value> bursts. If 0 or not specified, + * AOA measurements will be disabled for this peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ: Frequency in MHz where + * the measurement frames are exchanged. Optional; if not + * specified, try to locate the peer in the kernel scan + * results cache and use frequency from there. + */ +enum qca_wlan_vendor_attr_ftm_peer_info { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_meas_flags: Measurement request flags, + * per-peer + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP: If set, request + * immediate (ASAP) response from peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI: If set, request + * LCI report from peer. The LCI report includes the absolute + * location of the peer in "official" coordinates (similar to GPS). + * See IEEE P802.11-REVmc/D7.0, 11.24.6.7 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR: If set, request + * Location civic report from peer. The LCR includes the location + * of the peer in free-form format. See IEEE P802.11-REVmc/D7.0, + * 11.24.6.7 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE: If set, + * request a secure measurement. + * QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID must also be provided. + */ +enum qca_wlan_vendor_attr_ftm_peer_meas_flags { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP = 1 << 0, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI = 1 << 1, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR = 1 << 2, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE = 1 << 3, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_meas_param: Measurement parameters + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST: Number of measurements + * to perform in a single burst. + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP: Number of bursts to + * perform, specified as an exponent (2^value). + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION: Duration of burst + * instance, as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167. + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD: Time between bursts, + * as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167. Must + * be larger than QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION. + */ +enum qca_wlan_vendor_attr_ftm_meas_param { + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result: Per-peer results + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR: MAC address of the reported + * peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS: Status of measurement + * request for this peer. + * See enum qca_wlan_vendor_attr_ftm_peer_result_status. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS: Various flags related + * to measurement results for this peer. + * See enum qca_wlan_vendor_attr_ftm_peer_result_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS: Specified when + * request failed and peer requested not to send an additional request + * for this number of seconds. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI: LCI report when received + * from peer. In the format specified by IEEE P802.11-REVmc/D7.0, + * 9.4.2.22.10. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR: Location civic report when + * received from peer. In the format specified by IEEE P802.11-REVmc/D7.0, + * 9.4.2.22.13. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS: Reported when peer + * overridden some measurement request parameters. See + * enum qca_wlan_vendor_attr_ftm_meas_param. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS: AOA measurement + * for this peer. Same contents as @QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS: Array of measurement + * results. Each entry is a nested attribute defined + * by enum qca_wlan_vendor_attr_ftm_meas. + */ +enum qca_wlan_vendor_attr_ftm_peer_result { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result_status + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK: Request sent ok and results + * will be provided. Peer may have overridden some measurement parameters, + * in which case overridden parameters will be report by + * QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAM attribute. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE: Peer is incapable + * of performing the measurement request. No more results will be sent + * for this peer in this session. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED: Peer reported request + * failed, and requested not to send an additional request for number + * of seconds specified by QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS + * attribute. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID: Request validation + * failed. Request was not sent over the air. + */ +enum qca_wlan_vendor_attr_ftm_peer_result_status { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result_flags: Various flags + * for measurement result, per-peer + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE: If set, + * measurement completed for this peer. No more results will be reported + * for this peer in this session. + */ +enum qca_wlan_vendor_attr_ftm_peer_result_flags { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE = 1 << 0, +}; + +/** + * enum qca_vendor_attr_loc_session_status: Session completion status code + * + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK: Session completed + * successfully. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED: Session aborted + * by request. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID: Session request + * was invalid and was not started. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED: Session had an error + * and did not complete normally (for example out of resources). + */ +enum qca_vendor_attr_loc_session_status { + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_meas: Single measurement data + * + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1: Time of departure (TOD) of FTM packet as + * recorded by responder, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2: Time of arrival (TOA) of FTM packet at + * initiator, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3: TOD of ACK packet as recorded by + * initiator, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4: TOA of ACK packet at + * responder, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI: RSSI (signal level) as recorded + * during this measurement exchange. Optional and will be provided if + * the hardware can measure it. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR: TOD error reported by + * responder. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR: TOA error reported by + * responder. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR: TOD error measured by + * initiator. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR: TOA error measured by + * initiator. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD: Dummy attribute for padding. + */ +enum qca_wlan_vendor_attr_ftm_meas { + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_aoa_type - AOA measurement type + * + * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: Phase of the strongest + * CIR (channel impulse response) path for each antenna. + * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: Phase and amplitude + * of the strongest CIR path for each antenna. + */ +enum qca_wlan_vendor_attr_aoa_type { + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE, + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP, + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_encryption_test - Attributes to + * validate encryption engine + * + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION: Flag attribute. + * This will be included if the request is for decryption; if not included, + * the request is treated as a request for encryption by default. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER: Unsigned 32-bit value + * indicating the key cipher suite. Takes same values as + * NL80211_ATTR_KEY_CIPHER. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID: Unsigned 8-bit value + * Key Id to be used for encryption + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK: Array of 8-bit values. + * Key (TK) to be used for encryption/decryption + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN: Array of 8-bit values. + * Packet number to be specified for encryption/decryption + * 6 bytes for TKIP/CCMP/GCMP. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA: Array of 8-bit values + * representing the 802.11 packet (header + payload + FCS) that + * needs to be encrypted/decrypted. + * Encrypted/decrypted response from the driver will also be sent + * to userspace with the same attribute. + */ +enum qca_wlan_vendor_attr_encryption_test { + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX = + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_dmg_rf_sector_type - Type of + * sector for DMG RF sector operations. + * + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_RX: RX sector + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_TX: TX sector + */ +enum qca_wlan_vendor_attr_dmg_rf_sector_type { + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_RX, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_TX, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_fw_state - State of firmware + * + * @QCA_WLAN_VENDOR_ATTR_FW_STATE_ERROR: FW is in bad state + * @QCA_WLAN_VENDOR_ATTR_FW_STATE_ACTIVE: FW is active + */ +enum qca_wlan_vendor_attr_fw_state { + QCA_WLAN_VENDOR_ATTR_FW_STATE_ERROR, + QCA_WLAN_VENDOR_ATTR_FW_STATE_ACTIVE, + QCA_WLAN_VENDOR_ATTR_FW_STATE_MAX +}; + +/** + * BRP antenna limit mode + * + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE: Disable BRP force + * antenna limit, BRP will be performed as usual. + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_EFFECTIVE: Define maximal + * antennas limit. the hardware may use less antennas than the + * maximum limit. + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_FORCE: The hardware will + * use exactly the specified number of antennas for BRP. + */ +enum qca_wlan_vendor_attr_brp_ant_limit_mode { + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_EFFECTIVE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_FORCE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_dmg_rf_sector_cfg - Attributes for + * DMG RF sector configuration for a single RF module. + * The values are defined in a compact way which closely matches + * the way it is stored in HW registers. + * The configuration provides values for 32 antennas and 8 distribution + * amplifiers, and together describes the characteristics of the RF + * sector - such as a beam in some direction with some gain. + * + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX: Index + * of RF module for this configuration. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE0: Bit 0 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE1: Bit 1 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE2: Bit 2 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_HI: Phase values + * for first 16 antennas, 2 bits per antenna. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_LO: Phase values + * for last 16 antennas, 2 bits per antenna. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16: Contains + * DTYPE values (3 bits) for each distribution amplifier, followed + * by X16 switch bits for each distribution amplifier. There are + * total of 8 distribution amplifiers. + */ +enum qca_wlan_vendor_attr_dmg_rf_sector_cfg { + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX = 1, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE0 = 2, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE1 = 3, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE2 = 4, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_HI = 5, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_LO = 6, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16 = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MAX = + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_set { + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING = 2, + /* 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_clr { + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_INVALID = 0, + /* Unsigned 32bit bitmap for clearing statistics + * All radio statistics 0x00000001 + * cca_busy_time (within radio statistics) 0x00000002 + * All channel stats (within radio statistics) 0x00000004 + * All scan statistics (within radio statistics) 0x00000008 + * All interface statistics 0x00000010 + * All tx rate statistics (within interface statistics) 0x00000020 + * All ac statistics (with in interface statistics) 0x00000040 + * All contention (min, max, avg) statistics (within ac statisctics) + * 0x00000080. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK = 1, + /* Unsigned 8 bit value: Request to stop statistics collection */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ = 2, + + /* Unsigned 32 bit bitmap: Response from the driver + * for the cleared statistics + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK = 3, + /* Unsigned 8 bit value: Response from driver/firmware + * for the stop request + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP = 4, + /* keep last */ + 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_get { + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_INVALID = 0, + /* Unsigned 32 bit 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 = 1, + /* Unsigned 32 bit value - bit mask to identify what statistics are + * requested for retrieval. + * Radio Statistics 0x00000001 + * Interface Statistics 0x00000020 + * All Peer Statistics 0x00000040 + * Peer Statistics 0x00000080 + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK = 2, + /* 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_results { + QCA_WLAN_VENDOR_ATTR_LL_STATS_INVALID = 0, + /* Unsigned 32bit value. Used by the driver; must match the request id + * provided with the QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET command. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_REQ_ID = 1, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX = 2, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX = 3, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX = 4, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX = 5, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT = 6, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA = 7, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK = 8, + + /* 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 = 9, + /* Interface MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR = 10, + /* Type = enum wifi_connection_state, e.g., DISCONNECTED, + * AUTHENTICATING, etc. valid for STA, CLI only. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE = 11, + /* Type = enum wifi_roam_state. Roaming state, e.g., IDLE or ACTIVE + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING = 12, + /* Unsigned 32 bit value. WIFI_CAPABILITY_XXX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES = 13, + /* NULL terminated SSID. An array of 33 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID = 14, + /* BSSID. An array of 6 unsigned 8 bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID = 15, + /* Country string advertised by AP. An array of 3 unsigned 8 bit + * values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR = 16, + /* Country string for this association. An array of 3 unsigned 8 bit + * values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR = 17, + + /* 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 = 18, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU = 19, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU = 20, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST = 21, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST = 22, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU = 23, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU = 24, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST = 25, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES = 26, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT = 27, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG = 28, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN = 29, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX = 30, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG = 31, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES = 32, + /* Unsigned 32 bit value. Number of peers */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS = 33, + + /* 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 = 34, + /* MAC addr corresponding to respective peer. An array of 6 unsigned + * 8 bit values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS = 35, + /* Unsigned int 32 bit value representing capabilities corresponding + * to respective peer. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES = 36, + /* Unsigned 32 bit value. Number of rates */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES = 37, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* + * are nested within the rate stat. + */ + + /* Wi-Fi Rate - separate attributes defined for individual fields */ + + /* Unsigned int 8 bit value; 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE = 38, + /* Unsigned int 8 bit value; 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS = 39, + /* Unsigned int 8 bit value; 0:20 MHz, 1:40 MHz, 2:80 MHz, 3:160 MHz */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW = 40, + /* Unsigned int 8 bit value; OFDM/CCK rate code would be as per IEEE Std + * in the units of 0.5 Mbps HT/VHT it would be MCS index + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX = 41, + + /* Unsigned 32 bit value. Bit rate in units of 100 kbps */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE = 42, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_STAT_* could be + * nested within the peer info stats. + */ + + /* Unsigned int 32 bit value. Number of successfully transmitted data + * packets, i.e., with ACK received corresponding to the respective + * rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU = 43, + /* Unsigned int 32 bit value. Number of received data packets + * corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU = 44, + /* Unsigned int 32 bit value. Number of data packet losses, i.e., no ACK + * received corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST = 45, + /* Unsigned int 32 bit value. Total number of data packet retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES = 46, + /* Unsigned int 32 bit value. Total number of short data packet retries + * for the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT = 47, + /* Unsigned int 32 bit value. Total number of long data packet retries + * for the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG = 48, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID = 49, + /* Unsigned 32 bit value. Total number of msecs the radio is awake + * accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME = 50, + /* Unsigned 32 bit value. Total number of msecs the radio is + * transmitting accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME = 51, + /* Unsigned 32 bit value. Total number of msecs the radio is in active + * receive accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME = 52, + /* Unsigned 32 bit 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 = 53, + /* Unsigned 32 bit 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 = 54, + /* Unsigned 32 bit 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 = 55, + /* Unsigned 32 bit 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 = 56, + /* Unsigned 32 bit 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 = 57, + /* Unsigned 32 bit value. Total number of msecs the radio is awake due + * to Hotspot 2.0 scans and GAS exchange accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20 = 58, + /* Unsigned 32 bit value. Number of channels. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS = 59, + + /* 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 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH = 60, + /* Unsigned 32 bit value. Primary 20 MHz channel. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ = 61, + /* Unsigned 32 bit value. Center frequency (MHz) first segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0 = 62, + /* Unsigned 32 bit value. Center frequency (MHz) second segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1 = 63, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_* could be + * nested within the radio stats. + */ + + /* Unsigned int 32 bit value representing total number of msecs the + * radio is awake on that channel accruing over time, corresponding to + * the respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME = 64, + /* Unsigned int 32 bit 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 = 65, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS = 66, + + /* Signifies the nested list of channel attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO = 67, + + /* Signifies the nested list of peer info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO = 68, + + /* Signifies the nested list of rate info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO = 69, + + /* Signifies the nested list of wmm info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO = 70, + + /* Unsigned 8 bit 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 = 71, + + /* Unsigned 64 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET = 72, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED = 73, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED = 74, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME = 75, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE = 76, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS = 77, + + /* Number of msecs the radio spent in transmitting for each power level + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL = 78, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_SUCC_CNT = 79, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_FAIL_CNT = 80, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT = 81, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT = 82, + + /* Unsigned int 32 value. + * Pending MSDUs corresponding to respective AC. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_PENDING_MSDU = 83, + + /* u32 value representing total time in milliseconds for which the radio + * is transmitting on this channel. This attribute will be nested + * within QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_TX_TIME = 84, + /* u32 value representing total time in milliseconds for which the radio + * is receiving all 802.11 frames intended for this device on this + * channel. This attribute will be nested within + * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85, + /* u8 value representing the channel load percentage. Possible values + * are 0-100. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86, + /* u8 value representing the time slicing duty cycle percentage. + * Possible values are 0-100. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87, + /* 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, +}; + +enum qca_wlan_vendor_attr_ll_stats_type { + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_INVALID = 0, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO = 1, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE = 2, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS = 3, + + /* keep last */ + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_AFTER_LAST, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_MAX = + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_tdls_configuration - Attributes for + * TDLS configuration to the host driver. + * + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE: Configure the TDLS trigger + * mode in the host driver. enum qca_wlan_vendor_tdls_trigger_mode + * represents the different TDLS trigger modes. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD: Duration (u32) within + * which QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD number + * of packets shall meet the criteria for implicit TDLS setup. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD: Number (u32) of Tx/Rx packets + * within a duration QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD + * to initiate a TDLS setup. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_DISCOVERY_PERIOD: Time (u32) to initiate + * a TDLS Discovery to the peer. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX_DISCOVERY_ATTEMPT: Max number (u32) of + * discovery attempts to know the TDLS capability of the peer. A peer is + * marked as TDLS not capable if there is no response for all the attempts. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT: Represents a duration (u32) + * within which QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD + * number of TX / RX frames meet the criteria for TDLS teardown. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD: Minimum number (u32) + * of Tx/Rx packets within a duration + * QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT to tear down a TDLS link. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_SETUP_RSSI_THRESHOLD: Threshold + * corresponding to the RSSI of the peer below which a TDLS setup is + * triggered. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TEARDOWN_RSSI_THRESHOLD: Threshold + * corresponding to the RSSI of the peer above which a TDLS teardown is + * triggered. + */ +enum qca_wlan_vendor_attr_tdls_configuration { + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE = 1, + + /* Attributes configuring the TDLS Implicit Trigger */ + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD = 2, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD = 3, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_DISCOVERY_PERIOD = 4, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX_DISCOVERY_ATTEMPT = 5, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT = 6, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD = 7, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_SETUP_RSSI_THRESHOLD = 8, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TEARDOWN_RSSI_THRESHOLD = 9, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_tdls_trigger_mode: Represents the TDLS trigger mode in + * the driver + * + * The following are the different values for + * QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE. + * + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: The trigger to initiate/teardown + * the TDLS connection to a respective peer comes from the user space. + * wpa_supplicant provides the commands TDLS_SETUP, TDLS_TEARDOWN, + * TDLS_DISCOVER to do this. + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: Host driver triggers this TDLS + * setup/teardown to the eligible peer once the configured criteria + * (such as TX/RX threshold, RSSI) is met. The attributes + * in QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IMPLICIT_PARAMS correspond to + * the different configuration criteria for the TDLS trigger from the + * host driver. + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: Enables the driver to trigger + * the TDLS setup / teardown through the implicit mode only to the + * configured MAC addresses (wpa_supplicant, with tdls_external_control=1, + * configures the MAC address through TDLS_SETUP / TDLS_TEARDOWN commands). + * External mode works on top of the implicit mode. Thus the host driver + * is expected to configure in TDLS Implicit mode too to operate in + * External mode. + * Configuring External mode alone without Implicit mode is invalid. + * + * All the above implementations work as expected only when the host driver + * advertises the capability WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP - representing + * that the TDLS message exchange is not internal to the host driver, but + * depends on wpa_supplicant to do the message exchange. + */ +enum qca_wlan_vendor_tdls_trigger_mode { + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT = 1 << 0, + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT = 1 << 1, + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL = 1 << 2, +}; + +/** + * enum qca_vendor_attr_sar_limits_selections - Source of SAR power limits + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0: Select SAR profile #0 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1: Select SAR profile #1 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2: Select SAR profile #2 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3: Select SAR profile #3 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4: Select SAR profile #4 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE: Do not select any + * source of SAR power limits, thereby disabling the SAR power + * limit feature. + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER: Select the SAR power + * limits configured by %QCA_NL80211_VENDOR_SUBCMD_SET_SAR. + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0: Select the SAR power + * limits version 2.0 configured by %QCA_NL80211_VENDOR_SUBCMD_SET_SAR. + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT in an instance of + * the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor command or in + * the response to an instance of the + * %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS vendor command. + */ +enum qca_vendor_attr_sar_limits_selections { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0 = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1 = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2 = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3 = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4 = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER = 6, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0 = 7, +}; + +/** + * enum qca_vendor_attr_sar_limits_spec_modulations - + * SAR limits specification modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK - + * CCK modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM - + * OFDM modulation + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION in an + * instance of attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC in an + * instance of the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor + * command or in the response to an instance of the + * %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS vendor command. + */ +enum qca_vendor_attr_sar_limits_spec_modulations { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM = 1, +}; + +/** + * enum qca_vendor_attr_sar_limits - Attributes for SAR power limits + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE: Optional (u32) value to + * select which SAR power limit table should be used. Valid + * values are enumerated in enum + * %qca_vendor_attr_sar_limits_selections. The existing SAR + * power limit selection is unchanged if this attribute is not + * present. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS: Optional (u32) value + * which specifies the number of SAR power limit specifications + * which will follow. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC: Nested array of SAR power + * limit specifications. The number of specifications is + * specified by @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS. Each + * specification contains a set of + * QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_* attributes. A + * specification is uniquely identified by the attributes + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND, + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN, and + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION and always + * contains as a payload the attribute + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT, + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX. + * Either %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT or + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX is + * needed based upon the value of + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND: Optional (u32) value to + * indicate for which band this specification applies. Valid + * values are enumerated in enum %nl80211_band (although not all + * bands may be supported by a given device). If the attribute is + * not supplied then the specification will be applied to all + * supported bands. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN: Optional (u32) value + * to indicate for which antenna chain this specification + * applies, i.e. 1 for chain 1, 2 for chain 2, etc. If the + * attribute is not supplied then the specification will be + * applied to all chains. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION: Optional (u32) + * value to indicate for which modulation scheme this + * specification applies. Valid values are enumerated in enum + * %qca_vendor_attr_sar_limits_spec_modulations. If the attribute + * is not supplied then the specification will be applied to all + * modulation schemes. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT: Required (u32) + * value to specify the actual power limit value in units of 0.5 + * dBm (i.e., a value of 11 represents 5.5 dBm). + * This is required, when %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT is + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX: Required (u32) + * value to indicate SAR V2 indices (0 - 11) to select SAR V2 profiles. + * This is required, when %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT is + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0. + * + * These attributes are used with %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS + * and %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS. + */ +enum qca_vendor_attr_sar_limits { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION = 6, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT = 7, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX = 8, + + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX = + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_get_wifi_info: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO sub command. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION: In a request this attribute + * should be set to any U8 value to indicate that the driver version + * should be returned. When enabled in this manner, in a response this + * attribute will contain a string representation of the driver version. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION: In a request this attribute + * should be set to any U8 value to indicate that the firmware version + * should be returned. When enabled in this manner, in a response this + * attribute will contain a string representation of the firmware version. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX: In a request this attribute + * should be set to any U32 value to indicate that the current radio + * index should be returned. When enabled in this manner, in a response + * this attribute will contain a U32 radio index value. + * + */ +enum qca_wlan_vendor_attr_get_wifi_info { + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION = 2, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST - 1, +}; + +/* + * enum qca_wlan_vendor_attr_wifi_logger_start: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START sub command. + */ +enum qca_wlan_vendor_attr_wifi_logger_start { + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL = 2, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_GET_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_logger_results { + QCA_WLAN_VENDOR_ATTR_LOGGER_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_LOGGER_RESULTS_REQUEST_ID = 1, + + /* Unsigned 32-bit value; used to indicate the size of memory + * dump to be allocated. + */ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_AFTER_LAST - 1, +}; + +/** + * enum qca_scan_freq_list_type: Frequency list types + * + * @QCA_PREFERRED_SCAN_FREQ_LIST: The driver shall use the scan frequency list + * specified with attribute QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST as + * a preferred frequency list for roaming. + * + * @QCA_SPECIFIC_SCAN_FREQ_LIST: The driver shall use the frequency list + * specified with attribute QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST as + * a specific frequency list for roaming. + */ +enum qca_scan_freq_list_type { + QCA_PREFERRED_SCAN_FREQ_LIST = 1, + QCA_SPECIFIC_SCAN_FREQ_LIST = 2, +}; + +/** + * enum qca_vendor_attr_scan_freq_list_scheme: Frequency list scheme + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST: Nested attribute of u32 values + * List of frequencies in MHz to be considered for a roam scan. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_TYPE: Unsigned 32-bit value. + * Type of frequency list scheme being configured/gotten as defined by the + * enum qca_scan_freq_list_type. + */ +enum qca_vendor_attr_scan_freq_list_scheme { + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST = 1, + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_TYPE = 2, + + /* keep last */ + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST, + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_MAX = + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST - 1, +}; + +/** + * enum qca_roam_scan_scheme: Scan scheme + * + * @QCA_ROAM_SCAN_SCHEME_NO_SCAN: No frequencies specified to scan. + * Indicates the driver to not scan on a Roam Trigger scenario, but + * disconnect. E.g., on a BTM request from the AP the driver/firmware shall + * disconnect from the current connected AP by notifying a failure + * code in the BTM response. + * + * @QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN: Indicates the driver/firmware to + * trigger partial frequency scans. These frequencies are the ones learned + * or maintained by the driver based on the probability of finding the + * BSSIDs in the ESS for which the roaming is triggered. + * + * @QCA_ROAM_SCAN_SCHEME_FULL_SCAN: Indicates the driver/firmware to + * trigger the scan on all the valid frequencies to find better + * candidates to roam. + */ +enum qca_roam_scan_scheme { + QCA_ROAM_SCAN_SCHEME_NO_SCAN = 0, + QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN = 1, + QCA_ROAM_SCAN_SCHEME_FULL_SCAN = 2, +}; + +/* + * enum qca_vendor_roam_triggers: Bitmap of roaming triggers + * + * @QCA_ROAM_TRIGGER_REASON_PER: Set if the roam has to be triggered based on + * a bad packet error rates (PER). + * @QCA_ROAM_TRIGGER_REASON_BEACON_MISS: Set if the roam has to be triggered + * based on beacon misses from the connected AP. + * @QCA_ROAM_TRIGGER_REASON_POOR_RSSI: Set if the roam has to be triggered + * due to poor RSSI of the connected AP. + * @QCA_ROAM_TRIGGER_REASON_BETTER_RSSI: Set if the roam has to be triggered + * upon finding a BSSID with a better RSSI than the connected BSSID. + * Here the RSSI of the current BSSID need not be poor. + * @QCA_ROAM_TRIGGER_REASON_PERIODIC: Set if the roam has to be triggered + * by triggering a periodic scan to find a better AP to roam. + * @QCA_ROAM_TRIGGER_REASON_DENSE: Set if the roam has to be triggered + * when the connected channel environment is too noisy/congested. + * @QCA_ROAM_TRIGGER_REASON_BTM: Set if the roam has to be triggered + * when BTM Request frame is received from the connected AP. + * @QCA_ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered + * when the channel utilization is goes above the configured threshold. + * @QCA_ROAM_TRIGGER_REASON_USER_TRIGGER: Set if the roam has to be triggered + * based on the request from the user (space). + * @QCA_ROAM_TRIGGER_REASON_DEAUTH: Set if the roam has to be triggered when + * device receives Deauthentication/Disassociation frame from connected AP. + * @QCA_ROAM_TRIGGER_REASON_IDLE: Set if the roam has to be triggered when the + * device is in idle state (no TX/RX) and suspend mode, if the current RSSI + * is determined to be a poor one. + * @QCA_ROAM_TRIGGER_REASON_TX_FAILURES: Set if the roam has to be triggered + * based on continuous TX Data frame failures to the connected AP. + * @QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN: Set if the roam has to be triggered + * based on the scan results obtained from an external scan (not triggered + * to aim roaming). + * + * Set the corresponding roam trigger reason bit to consider it for roam + * trigger. + * Userspace can set multiple bits and send to the driver. The driver shall + * consider all of them to trigger/initiate a roam scan. + */ +enum qca_vendor_roam_triggers { + QCA_ROAM_TRIGGER_REASON_PER = 1 << 0, + QCA_ROAM_TRIGGER_REASON_BEACON_MISS = 1 << 1, + QCA_ROAM_TRIGGER_REASON_POOR_RSSI = 1 << 2, + QCA_ROAM_TRIGGER_REASON_BETTER_RSSI = 1 << 3, + QCA_ROAM_TRIGGER_REASON_PERIODIC = 1 << 4, + QCA_ROAM_TRIGGER_REASON_DENSE = 1 << 5, + QCA_ROAM_TRIGGER_REASON_BTM = 1 << 6, + QCA_ROAM_TRIGGER_REASON_BSS_LOAD = 1 << 7, + QCA_ROAM_TRIGGER_REASON_USER_TRIGGER = 1 << 8, + QCA_ROAM_TRIGGER_REASON_DEAUTH = 1 << 9, + QCA_ROAM_TRIGGER_REASON_IDLE = 1 << 10, + QCA_ROAM_TRIGGER_REASON_TX_FAILURES = 1 << 11, + QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN = 1 << 12, +}; + +/* + * enum qca_vendor_roam_fail_reasons: Defines the various roam + * fail reasons. This enum value is used in + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute. + * + * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not + * able to trigger the scan. + * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan. + * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam + * scan. + * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host. + * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame. + * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error + * status code. + * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received. + * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request + * frame. + * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame + * with error status code. + * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not + * received. + * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan. + * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication + * frame. + * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped + * internally before transmission. + * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation + * Request frame. + * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is + * dropped internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and + * times out. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped + * internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key + * M2 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped + * internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4 + * frame. + * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not + * started for final beacon miss case. + * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame + * received from the AP during roaming handoff. + * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps + * or host is suspended and gives the indication of the last roamed AP only + * when the Apps is resumed. If the Apps is resumed while the roaming is in + * progress, this ongoing roaming is aborted and the last roamed AP is + * indicated to host. + * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID. + * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times + * out. + * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails. + */ +enum qca_vendor_roam_fail_reasons { + QCA_ROAM_FAIL_REASON_NONE = 0, + QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1, + QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2, + QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3, + QCA_ROAM_FAIL_REASON_HOST = 4, + QCA_ROAM_FAIL_REASON_AUTH_SEND = 5, + QCA_ROAM_FAIL_REASON_AUTH_RECV = 6, + QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7, + QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8, + QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9, + QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10, + QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11, + QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12, + QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13, + QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14, + QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15, + QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16, + QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17, + QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18, + QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19, + QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20, + QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21, + QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22, + QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23, + QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24, + QCA_ROAM_FAIL_REASON_DISCONNECT = 25, + QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26, + QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27, + QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28, + QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29, +}; + +/* + * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam + * invoke fail reasons. This enum value is used in + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute. + * + * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed + * in roam invoke command. + * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not + * enabled. + * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID + * length is invalid. + * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already + * in progress. + * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response + * of the AP in the roam invoke command to firmware. This reason is sent by the + * firmware when the given AP is configured to be ignored or SSID/security + * does not match. + * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of + * firmware internal reasons. + * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled. + * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke. + * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail. + * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid. + * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to. + * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed. + */ +enum qca_vendor_roam_invoke_fail_reasons { + QCA_ROAM_INVOKE_STATUS_NONE = 0, + QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1, + QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2, + QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3, + QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4, + QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5, + QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6, + QCA_ROAM_INVOKE_STATUS_DISALLOW = 7, + QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8, + QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9, + QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10, + QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11, + QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12, + +}; + +/** + * enum qca_vendor_attr_roam_candidate_selection_criteria: + * + * Each attribute carries a weightage in percentage (%). + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_RSSI: Unsigned 8-bit value. + * Represents the weightage to be given for the RSSI selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE: Unsigned 8-bit value. + * Represents the weightage to be given for the rate selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BW: Unsigned 8-bit value. + * Represents the weightage to be given for the band width selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BAND: Unsigned 8-bit value. + * Represents the weightage to be given for the band selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_NSS: Unsigned 8-bit value. + * Represents the weightage to be given for the NSS selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_CHAN_CONGESTION: Unsigned 8-bit value. + * Represents the weightage to be given for the channel congestion + * selection criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BEAMFORMING: Unsigned 8-bit value. + * Represents the weightage to be given for the beamforming selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_OCE_WAN: Unsigned 8-bit value. + * Represents the weightage to be given for the OCE selection + * criteria among other parameters. + */ +enum qca_vendor_attr_roam_candidate_selection_criteria { + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_RSSI = 1, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE = 2, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BW = 3, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BAND = 4, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_NSS = 5, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_CHAN_CONGESTION = 6, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BEAMFORMING = 7, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_OCE_WAN = 8, + + /* keep last */ + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_AFTER_LAST, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_MAX = + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_roam_control - Attributes to carry roam configuration + * The following attributes are used to set/get/clear the respective + * configurations to/from the driver. + * For the get, the attribute for the configuration to be queried shall + * carry any of its acceptable values to the driver. In return, the driver + * shall send the configured values within the same attribute to the user + * space. + * + * @QCA_ATTR_ROAM_CONTROL_ENABLE: Unsigned 8-bit value. + * Signifies to enable/disable roam control in driver. + * 1-enable, 0-disable + * Enable: Mandates the driver to do the further roams using the + * configuration parameters set through + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET. + * Disable: Disables the driver/firmware roaming triggered through + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET. Further roaming is + * expected to continue with the default configurations. + * + * @QCA_ATTR_ROAM_CONTROL_STATUS: Unsigned 8-bit value. + * This is used along with QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET. + * Roam control status is obtained through this attribute. + * + * @QCA_ATTR_ROAM_CONTROL_CLEAR_ALL: Flag attribute to indicate the + * complete config set through QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET + * is to be cleared in the driver. + * This is used along with QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR + * and shall be ignored if used with other sub commands. + * If this attribute is specified along with subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR, the driver shall ignore + * all other attributes, if there are any. + * If this attribute is not specified when the subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR is sent, the driver shall + * clear the data corresponding to the attributes specified. + * + * @QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME: Nested attribute to carry the + * list of frequencies and its type, represented by + * enum qca_vendor_attr_scan_freq_list_scheme. + * Frequency list and its type are mandatory for this attribute to set + * the frequencies. + * Frequency type is mandatory for this attribute to get the frequencies + * and the frequency list is obtained through + * QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST. + * Frequency list type is mandatory for this attribute to clear the + * frequencies. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD: Unsigned 32-bit value. + * Carries the value of scan period in seconds to set. + * The value of scan period is obtained with the same attribute for get. + * Clears the scan period in the driver when specified with clear command. + * Scan period is the idle time in seconds between each subsequent + * channel scans. + * + * @QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD: Unsigned 32-bit value. + * Carries the value of full scan period in seconds to set. + * The value of full scan period is obtained with the same attribute for + * get. + * Clears the full scan period in the driver when specified with clear + * command. Full scan period is the idle period in seconds between two + * successive full channel roam scans. + * + * @QCA_ATTR_ROAM_CONTROL_TRIGGERS: Unsigned 32-bit value. + * Carries a bitmap of the roam triggers specified in + * enum qca_vendor_roam_triggers. + * The driver shall enable roaming by enabling corresponding roam triggers + * based on the trigger bits sent with this attribute. + * If this attribute is not configured, the driver shall proceed with + * default behavior. + * The bitmap configured is obtained with the same attribute for get. + * Clears the bitmap configured in driver when specified with clear + * command. + * + * @QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA: Nested attribute signifying the + * weightage in percentage (%) to be given for each selection criteria. + * Different roam candidate selection criteria are represented by + * enum qca_vendor_attr_roam_candidate_selection_criteria. + * The driver shall select the roam candidate based on corresponding + * candidate selection scores sent. + * + * An empty nested attribute is used to indicate that no specific + * preference score/criteria is configured (i.e., to disable this mechanism + * in the set case and to show that the mechanism is disabled in the get + * case). + * + * Userspace can send multiple attributes out of this enum to the driver. + * Since this attribute represents the weight/percentage of preference for + * the respective selection criteria, it is preferred to configure 100% + * total weightage. The value in each attribute or cumulative weight of the + * values in all the nested attributes should not exceed 100%. The driver + * shall reject such configuration. + * + * If the weights configured through this attribute are less than 100%, + * the driver shall honor the weights (x%) passed for the corresponding + * selection criteria and choose/distribute rest of the weight (100-x)% + * for the other selection criteria, based on its internal logic. + * + * The selection criteria configured is obtained with the same + * attribute for get. + * + * Clears the selection criteria configured in the driver when specified + * with clear command. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME: Unsigned 32-bit value. + * Represents value of the scan frequency scheme from enum + * qca_roam_scan_scheme. + * It's an optional attribute. If this attribute is not configured, the + * driver shall proceed with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD: Signed 32-bit value in dBm, + * signifying the RSSI threshold of the current connected AP, indicating + * the driver to trigger roam only when the current connected AP's RSSI + * is less than this threshold. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm, + * signifying the RSSI threshold of the candidate AP, indicating + * the driver to trigger roam only to the candidate AP with RSSI + * better than this threshold. If RSSI thresholds for candidate APs found + * in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ, + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will + * take precedence over the value configured using the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute. + * + * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the + * user defined reason code to be sent to the AP in response to AP's + * request to trigger the roam if the roaming cannot be triggered. + * Applies to all the scenarios of AP assisted roaming (e.g., BTM). + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS: Unsigned 32-bit value. + * Carries a bitmap of the roam triggers specified in + * enum qca_vendor_roam_triggers. + * Represents the roam triggers for which the specific scan scheme from + * enum qca_roam_scan_scheme has to be applied. + * It's an optional attribute. If this attribute is not configured, but + * QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is specified, the scan scheme + * specified through QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is applicable for + * all the roams. + * If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and + * QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the + * driver shall proceed with the default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value + * in dBm, signifying the RSSI threshold of the candidate AP found in the + * 2.4 GHz band. The driver/firmware shall trigger roaming to the candidate + * AP found in the 2.4 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in + * dBm, signifying the RSSI threshold of the candidate AP found in the 5 + * GHz band. The driver/firmware shall trigger roaming to the candidate AP + * found in the 5 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by tge + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in + * dBm, signifying the RSSI threshold of the candidate AP found in the 6 + * GHz band. The driver/firmware shall trigger roaming to the candidate AP + * found in the 6 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value. + * Carries bitmask value of bits from &enum qca_set_band and represents + * all the bands in which roaming is allowed. The configuration is valid + * until next disconnection. If this attribute is not present, the + * existing configuration shall be used. By default, roaming is allowed on + * all bands supported by the local device. When the value is set to + * %QCA_SETBAND_AUTO, all supported bands shall be enabled. + * + * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz + * bands. If this attribute is not configured, the driver shall proceed + * with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for passive channels in the 5 GHz + * band. If this attribute is not configured, the driver shall proceed with + * default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds. + * Optional parameter. The minimum duration to stay on the connected AP + * channel during the channel scanning. If this attribute is not + * configured, the driver shall proceed with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds. + * Optional parameter. The maximum duration for which the radio can scan + * foreign channels consecutively without coming back to home channel. If + * this attribute is not configured, the driver shall proceed with default + * behavior. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for 6G Preferred Scanning Channels. + * If this attribute is not configured, the driver shall proceed with + * default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for 6G Non Preferred Scanning + * Channels. If this attribute is not configured, the driver shall proceed + * with default behavior. + */ +enum qca_vendor_attr_roam_control { + QCA_ATTR_ROAM_CONTROL_ENABLE = 1, + QCA_ATTR_ROAM_CONTROL_STATUS = 2, + QCA_ATTR_ROAM_CONTROL_CLEAR_ALL = 3, + QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME= 4, + QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD = 5, + QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD = 6, + QCA_ATTR_ROAM_CONTROL_TRIGGERS = 7, + QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA = 8, + QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME = 9, + QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD = 10, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11, + QCA_ATTR_ROAM_CONTROL_USER_REASON = 12, + QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16, + QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17, + QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18, + QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19, + QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20, + QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21, + QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22, + QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23, + + /* keep last */ + QCA_ATTR_ROAM_CONTROL_AFTER_LAST, + QCA_ATTR_ROAM_CONTROL_MAX = + QCA_ATTR_ROAM_CONTROL_AFTER_LAST - 1, +}; + +/* + * enum qca_wlan_vendor_attr_roaming_config_params: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_ROAM sub command. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD: Unsigned 32-bit value. + * Represents the different roam sub commands referred by + * enum qca_wlan_vendor_roaming_subcmd. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID: Unsigned 32-bit value. + * Represents the Request ID for the specific set of commands. + * This also helps to map specific set of commands to the respective + * ID / client. e.g., helps to identify the user entity configuring the + * ignored BSSIDs and accordingly clear the respective ones with the + * matching ID. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS: Unsigned + * 32-bit value. Represents the number of allowlist SSIDs configured. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST: Nested attribute + * to carry the list of allowlist SSIDs. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID: SSID (binary attribute, + * 0..32 octets). Represents the allow list SSID. Allowlist SSIDs + * represent the list of SSIDs to which the firmware/driver can consider + * to roam to. + * + * The following PARAM_A_BAND_XX attributes are applied to 5GHz BSSIDs when + * comparing with a 2.4GHz BSSID. They are not applied when comparing two + * 5GHz BSSIDs.The following attributes are set through the Roaming SUBCMD - + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD: Signed 32-bit + * value, RSSI threshold above which 5GHz RSSI is favored. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD: Signed 32-bit + * value, RSSI threshold below which 5GHz RSSI is penalized. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR: Unsigned 32-bit + * value, factor by which 5GHz RSSI is boosted. + * boost=(RSSI_measured-5GHz_boost_threshold)*5GHz_boost_factor + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR: Unsigned 32-bit + * value, factor by which 5GHz RSSI is penalized. + * penalty=(5GHz_penalty_threshold-RSSI_measured)*5GHz_penalty_factor + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST: Unsigned 32-bit + * value, maximum boost that can be applied to a 5GHz RSSI. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS: Unsigned 32-bit + * value, boost applied to current BSSID to ensure the currently + * associated BSSID is favored so as to prevent ping-pong situations. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER: Signed 32-bit + * value, RSSI below which "Alert" roam is enabled. + * "Alert" mode roaming - firmware is "urgently" hunting for another BSSID + * because the RSSI is low, or because many successive beacons have been + * lost or other bad link conditions. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE: Unsigned 32-bit + * value. 1-Enable, 0-Disable. Represents "Lazy" mode, where + * firmware is hunting for a better BSSID or allow listed SSID even though + * the RSSI of the link is good. The parameters enabling the roaming are + * configured through the PARAM_A_BAND_XX attrbutes. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS: Nested attribute, + * represents the BSSIDs preferred over others while evaluating them + * for the roaming. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID: Unsigned + * 32-bit value. Represents the number of preferred BSSIDs set. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID: 6-byte MAC + * address representing the BSSID to be preferred. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER: Signed + * 32-bit value, representing the modifier to be applied to the RSSI of + * the BSSID for the purpose of comparing it with other roam candidate. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS: Nested attribute, + * represents the BSSIDs to get ignored for roaming. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID: Unsigned + * 32-bit value, represents the number of ignored BSSIDs. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID: 6-byte MAC + * address representing the ignored BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT: Flag attribute, + * indicates this request to ignore the BSSID as a hint to the driver. The + * driver can select this BSSID in the worst case (when no other BSSIDs are + * better). + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL: Nested attribute to + * set/get/clear the roam control config as + * defined @enum qca_vendor_attr_roam_control. + */ +enum qca_wlan_vendor_attr_roaming_config_params { + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD = 1, + QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID = 2, + + /* Attributes for wifi_set_ssid_allow_list */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS = 3, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST = 4, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID = 5, + + /* Attributes for set_roam_params */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD = 6, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD = 7, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR = 8, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR = 9, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST = 10, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS = 11, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER = 12, + + /* Attribute for set_lazy_roam */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE = 13, + + /* Attribute for set_lazy_roam with preferences */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS = 14, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID = 15, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID = 16, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER = 17, + + /* Attribute for setting ignored BSSID parameters */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20, + /* Flag attribute indicates this entry as a hint */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT = 21, + + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL = 22, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST - 1, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID + +/* + * enum qca_wlan_vendor_roaming_subcmd: Referred by + * QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST: Sub command to + * configure the allow list SSIDs. These are configured through + * the following attributes. + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS, + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST, + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS: Sub command to + * configure the Roam params. These parameters are evaluated on the GScan + * results. Refers the attributes PARAM_A_BAND_XX above to configure the + * params. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM: Sets the Lazy roam. Uses + * the attribute QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE + * to enable/disable Lazy roam. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS: Sets the BSSID + * preference. Contains the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS to set the BSSID + * preference. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID: Sets the list of BSSIDs + * to ignore in roaming decision. Uses + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS to set the list. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET: Command to set the + * roam control config to the driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET: Command to obtain the + * roam control config from driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * For the get, the attribute for the configuration to be queried shall + * carry any of its acceptable value to the driver. In return, the driver + * shall send the configured values within the same attribute to the user + * space. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR: Command to clear the + * roam control config in the driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * The driver shall continue with its default roaming behavior when data + * corresponding to an attribute is cleared. + */ +enum qca_wlan_vendor_roaming_subcmd { + QCA_WLAN_VENDOR_ROAMING_SUBCMD_INVALID = 0, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST = 1, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS = 2, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM = 3, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS = 4, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PARAMS = 5, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID = 6, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET = 7, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET = 8, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR = 9, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST \ + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST +#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID \ + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID + +enum qca_wlan_vendor_attr_gscan_config_params { + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0, + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID = 1, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND + = 2, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS + = 3, + + /* Attributes for input params used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_START sub command. + */ + + /* Unsigned 32-bit value; channel frequency */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL = 4, + /* Unsigned 32-bit value; dwell time in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME = 5, + /* Unsigned 8-bit value; 0: active; 1: passive; N/A for DFS */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE = 6, + /* Unsigned 8-bit value; channel class */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CLASS = 7, + + /* Unsigned 8-bit value; bucket index, 0 based */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX = 8, + /* Unsigned 8-bit value; band. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND = 9, + /* Unsigned 32-bit value; desired period, in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD = 10, + /* Unsigned 8-bit value; report events semantics. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS = 11, + /* Unsigned 32-bit value. Followed by a nested array of + * GSCAN_CHANNEL_SPEC_* attributes. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS = 12, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC = 13, + + /* Unsigned 32-bit value; base timer period in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD = 14, + /* 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_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN = 15, + /* Unsigned 8-bit value; in %, when scan buffer is this much full, wake + * up AP. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT + = 16, + + /* Unsigned 8-bit value; number of scan bucket specs; followed by a + * nested array of_GSCAN_BUCKET_SPEC_* attributes and values. The size + * of the array is determined by NUM_BUCKETS. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS = 17, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC = 18, + + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH + = 19, + /* Unsigned 32-bit value; maximum number of results to be returned. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX + = 20, + + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID = 21, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW = 22, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH = 23, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL = 24, + + /* 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_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP = 25, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM = 26, + + /* Unsigned 32-bit value; number of samples for averaging RSSI. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE + = 27, + /* Unsigned 32-bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE + = 28, + /* Unsigned 32-bit value; number of APs breaching threshold. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING = 29, + /* Unsigned 32-bit value; number of APs. Followed by an array of + * AP_THRESHOLD_PARAM attributes. Size of the array is NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP = 30, + /* Unsigned 32-bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE + = 31, + /* Unsigned 32-bit value. If max_period is non zero or different than + * period, then this bucket is an exponential backoff bucket. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_MAX_PERIOD = 32, + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BASE = 33, + /* Unsigned 32-bit value. For exponential back off bucket, number of + * scans to perform for a given period. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_STEP_COUNT = 34, + /* Unsigned 8-bit value; in number of scans, wake up AP after these + * many scans. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS + = 35, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST sub command. + */ + /* Unsigned 3-2bit value; number of samples to confirm SSID loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE + = 36, + /* Number of hotlist SSIDs as unsigned 32-bit value, followed by a + * nested array of SSID_THRESHOLD_PARAM_* attributes and values. The + * size of the array is determined by NUM_SSID. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_NUM_SSID = 37, + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_* + * attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_NUM_SSID + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM = 38, + + /* An array of 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_SSID = 39, + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_BAND = 40, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW = 41, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH = 42, + /* Unsigned 32-bit value; a bitmask with additional gscan config flag. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CONFIGURATION_FLAGS = 43, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_gscan_results { + QCA_WLAN_VENDOR_ATTR_GSCAN_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_GSCAN_RESULTS_REQUEST_ID = 1, + + /* Unsigned 32-bit value; used to indicate the status response from + * firmware/driver for the vendor sub-command. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS = 2, + + /* GSCAN Valid Channels attributes */ + /* Unsigned 32bit value; followed by a nested array of CHANNELS. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS = 3, + /* An array of NUM_CHANNELS x unsigned 32-bit value integers + * representing channel numbers. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS = 4, + + /* GSCAN Capabilities attributes */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE = 5, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS = 6, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN + = 7, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE + = 8, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD + = 9, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS = 10, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS + = 11, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES + = 12, + + /* GSCAN Attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE sub-command. + */ + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE = 13, + + /* GSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT sub-command. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_* + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST = 14, + + /* Unsigned 64-bit value; age of sample at the time of retrieval */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP = 15, + /* 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID = 16, + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID = 17, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL = 18, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI = 19, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT = 20, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD = 21, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD = 22, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY = 23, + /* Unsigned 32-bit value; size of the IE DATA blob */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH = 24, + /* 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_GSCAN_RESULTS_SCAN_RESULT_IE_DATA = 25, + + /* Unsigned 8-bit value; set by driver to indicate more scan results are + * available. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA = 26, + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT sub-command. + */ + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE = 27, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS = 28, + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of results. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the + * list of results. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE sub-command. + */ + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID = 29, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL + = 30, + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI + = 31, + /* 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_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST + = 32, + + /* GSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of gscan cached results returned. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST to indicate + * the list of gscan cached results. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_NL80211_VENDOR_ATTR_GSCAN_CACHED_RESULTS_* + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST = 33, + /* Unsigned 32-bit value; a unique identifier for the scan unit. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID = 34, + /* Unsigned 32-bit value; a bitmask w/additional information about scan. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS = 35, + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of wifi scan results/bssids retrieved by the scan. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the + * list of wifi scan results returned for each cached result block. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND sub-command. + */ + /* Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE for + * number of results. + * Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each + * wifi_passpoint_match_result block. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND sub-command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES + = 36, + /* A nested array of + * QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_* + * attributes. Array size = + * *_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST = 37, + + /* Unsigned 32-bit value; network block id for the matched network */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID = 38, + /* Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each + * wifi_passpoint_match_result block. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN = 39, + /* An array size of PASSPOINT_MATCH_ANQP_LEN of unsigned 8-bit values; + * ANQP data in the information_element format. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP = 40, + + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS = 41, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS = 42, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID + = 43, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID + = 44, + + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED = 45, + + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. + * This is used to limit the maximum number of BSSIDs while sending + * the vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM with subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID and attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID = 46, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST - 1, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID \ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID +#define QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID \ + QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID + +enum qca_wlan_vendor_attr_pno_config_params { + QCA_WLAN_VENDOR_ATTR_PNO_INVALID = 0, + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM = 1, + /* Array of nested QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_* + * attributes. Array size = + * QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY = 2, + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID = 3, + /* An array of 256 x unsigned 8-bit value; NULL terminated UTF-8 encoded + * realm, 0 if unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM = 4, + /* An array of 16 x unsigned 32-bit value; roaming consortium ids to + * match, 0 if unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID = 5, + /* An array of 6 x unsigned 8-bit value; MCC/MNC combination, 0s if + * unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN = 6, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS = 7, + /* Array of nested + * QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_* + * attributes. Array size = + * QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST = 8, + /* An array of 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID = 9, + /* Signed 8-bit value; threshold for considering this SSID as found, + * required granularity for this threshold is 4 dBm to 8 dBm. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_RSSI_THRESHOLD + = 10, + /* Unsigned 8-bit value; WIFI_PNO_FLAG_XXX */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS = 11, + /* Unsigned 8-bit value; auth bit field for matching WPA IE */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT = 12, + /* Unsigned 8-bit to indicate ePNO type; + * It takes values from qca_wlan_epno_type + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_TYPE = 13, + + /* Nested attribute to send the channel list */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_CHANNEL_LIST = 14, + + /* Unsigned 32-bit value; indicates the interval between PNO scan + * cycles in msec. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_SCAN_INTERVAL = 15, + QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI = 16, + QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI = 17, + QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX = 18, + QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS = 19, + QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS = 20, + QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS = 21, + QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS = 22, + /* Unsigned 32-bit value, representing the PNO Request ID */ + QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID = 23, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PNO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PNO_MAX = + QCA_WLAN_VENDOR_ATTR_PNO_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_acs_select_reason: This represents the different reasons why + * the ACS has to be triggered. These values are used by + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON and + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON + */ +enum qca_wlan_vendor_acs_select_reason { + /* Represents the reason that the ACS triggered during the AP start */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT, + /* Represents the reason that DFS found with the current channel */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS, + /* Represents the reason that LTE co-exist in the current band. */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX, + /* Represents the reason that generic, uncategorized interference has + * been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_GENERIC_INTERFERENCE, + /* Represents the reason that excessive 802.11 interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_80211_INTERFERENCE, + /* Represents the reason that generic Continuous Wave (CW) interference + * has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_CW_INTERFERENCE, + /* Represents the reason that Microwave Oven (MWO) interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_MWO_INTERFERENCE, + /* Represents the reason that generic Frequency-Hopping Spread Spectrum + * (FHSS) interference has been found in the current channel. This may + * include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_FHSS_INTERFERENCE, + /* Represents the reason that non-802.11 generic Frequency-Hopping + * Spread Spectrum (FHSS) interference has been found in the current + * channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_FHSS_INTERFERENCE, + /* Represents the reason that generic Wideband (WB) interference has + * been found in the current channel. This may include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_WB_INTERFERENCE, + /* Represents the reason that non-802.11 generic Wideband (WB) + * interference has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_WB_INTERFERENCE, + /* Represents the reason that Jammer interference has been found in the + * current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_JAMMER_INTERFERENCE, + /* Represents the reason that ACS triggered by AFC */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_AFC_TRIGGER, +}; + +/** + * qca_wlan_vendor_attr_external_acs_policy: Attribute values for + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This represents the + * external ACS policies to select the channels w.r.t. the PCL weights. + * (QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL represents the channels and + * their PCL weights.) + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY: Mandatory to + * select a channel with non-zero PCL weight. + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED: Prefer a + * channel with non-zero PCL weight. + * + */ +enum qca_wlan_vendor_attr_external_acs_policy { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY, +}; + +/** + * qca_wlan_vendor_channel_prop_flags: This represent the flags for a channel. + * This is used by QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS. + */ +enum qca_wlan_vendor_channel_prop_flags { + /* Bits 0, 1, 2, and 3 are reserved */ + + /* Turbo channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_TURBO = 1 << 4, + /* CCK channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_CCK = 1 << 5, + /* OFDM channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_OFDM = 1 << 6, + /* 2.4 GHz spectrum channel. */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_2GHZ = 1 << 7, + /* 5 GHz spectrum channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_5GHZ = 1 << 8, + /* Only passive scan allowed */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_PASSIVE = 1 << 9, + /* Dynamic CCK-OFDM channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_DYN = 1 << 10, + /* GFSK channel (FHSS PHY) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_GFSK = 1 << 11, + /* Radar found on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_RADAR = 1 << 12, + /* 11a static turbo channel only */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_STURBO = 1 << 13, + /* Half rate channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HALF = 1 << 14, + /* Quarter rate channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_QUARTER = 1 << 15, + /* HT 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT20 = 1 << 16, + /* HT 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40PLUS = 1 << 17, + /* HT 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40MINUS = 1 << 18, + /* HT 40 intolerant */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40INTOL = 1 << 19, + /* VHT 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT20 = 1 << 20, + /* VHT 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT40PLUS = 1 << 21, + /* VHT 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT40MINUS = 1 << 22, + /* VHT 80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT80 = 1 << 23, + /* HT 40 intolerant mark bit for ACS use */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40INTOLMARK = 1 << 24, + /* Channel temporarily blocked due to noise */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_BLOCKED = 1 << 25, + /* VHT 160 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT160 = 1 << 26, + /* VHT 80+80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT80_80 = 1 << 27, + /* HE 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE20 = 1 << 28, + /* HE 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40PLUS = 1 << 29, + /* HE 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40MINUS = 1 << 30, + /* HE 40 intolerant */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOL = 1 << 31, +}; + +/** + * qca_wlan_vendor_channel_prop_flags_2: This represents the flags for a + * channel, and is a continuation of qca_wlan_vendor_channel_prop_flags. This is + * used by QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2. + */ +enum qca_wlan_vendor_channel_prop_flags_2 { + /* HE 40 intolerant mark bit for ACS use */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOLMARK = 1 << 0, + /* HE 80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE80 = 1 << 1, + /* HE 160 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE160 = 1 << 2, + /* HE 80+80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE80_80 = 1 << 3, +}; + +/** + * qca_wlan_vendor_channel_prop_flags_ext: This represent the extended flags for + * each channel. This is used by + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT. + */ +enum qca_wlan_vendor_channel_prop_flags_ext { + /* Radar found on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_RADAR_FOUND = 1 << 0, + /* DFS required on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS = 1 << 1, + /* DFS required on channel for 2nd band of 80+80 */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS_CFREQ2 = 1 << 2, + /* If channel has been checked for DFS */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS_CLEAR = 1 << 3, + /* Excluded in 802.11d */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_11D_EXCLUDED = 1 << 4, + /* Channel Switch Announcement received on this channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_CSA_RECEIVED = 1 << 5, + /* Ad-hoc is not allowed */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DISALLOW_ADHOC = 1 << 6, + /* Station only channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DISALLOW_HOSTAP = 1 << 7, + /* DFS radar history for client device (STA mode) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_HISTORY_RADAR = 1 << 8, + /* DFS CAC valid for client device (STA mode) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_CAC_VALID = 1 << 9, +}; + +/** + * qca_wlan_vendor_external_acs_event_chan_info_attr: Represents per channel + * information. These attributes are sent as part of + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO. Each set of the following + * attributes correspond to a single channel. + */ +enum qca_wlan_vendor_external_acs_event_chan_info_attr { + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_INVALID = 0, + + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS = 1, + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags_ext. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT = 2, + /* frequency in MHz (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ = 3, + /* maximum regulatory transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER = 4, + /* maximum transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER = 5, + /* minimum transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER = 6, + /* regulatory class id (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID = 7, + /* maximum antenna gain in (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN = 8, + /* VHT segment 0 (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 = 9, + /* VHT segment 1 (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 = 10, + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags_2. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2 = 11, + + /* + * VHT segment 0 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * should be used. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 = 12, + + /* + * VHT segment 1 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * should be considered. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 = 13, + + /* + * 16-bit attribute of bits indicating the AP power modes supported by + * the channel (u16). + * Note: Currently, only 3 bits are used in the attribute and each bit + * corresponds to the power mode mentioned in enum + * qca_wlan_vendor_external_acs_chan_power_mode and a given bit is + * set if the associated mode is supported. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_SUPP_POWER_MODES + = 14, + /* Array of nested attributes for each power mode. It takes attr as + * defined in enum + * qca_wlan_vendor_external_acs_event_chan_power_info_attr. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR = 15, + /* keep last */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST, + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX = + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST - 1, +}; + +/** + * qca_wlan_vendor_external_acs_chan_power_mode - Specifies the valid + * values that the vendor external ACS channel power attribute + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE can + * take. + * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_LOW_POWER: Low power/Indoor mode + * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_STANDARD_POWER: Standard power mode + * @QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_VERY_LOW_POWER: Very low power mode + */ +enum qca_wlan_vendor_external_acs_chan_power_level { + QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_LOW_POWER = 0, + QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_STANDARD_POWER = 1, + QCA_WLAN_VENDOR_EXTERNAL_ACS_CHAN_VERY_LOW_POWER = 2, +}; + +/** + * qca_wlan_vendor_external_acs_event_chan_power_info_attr: Represents nested + * attributes for power mode type and power values corresponding to that. + * These attributes are sent as part of + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR. + */ +enum qca_wlan_vendor_external_acs_event_chan_power_info_attr { + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_INVALID = 0, + /* + * Power mode (u8) takes the values defined in enum + * qca_wlan_vendor_external_acs_chan_power_mode + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE + = 1, + /* + * Indicates if power value is a PSD/EIRP value (flag). If flag is + * present, it indicates a PSD value. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_PSD_FLAG = 2, + /* + * Power value (u32) PSD/EIRP as indicated by + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_PSD_FLAG, + * for power mode corresponding to the + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_MODE. + * Units for PSD - dBm/MHz + * Units for EIRP - dBm + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_POWER_VALUE + = 3, + /* keep last */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_LAST, + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_MAX = + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_POWER_INFO_ATTR_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_pcl: Represents attributes for + * preferred channel list (PCL). These attributes are sent as part of + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL and + * QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST. + */ +enum qca_wlan_vendor_attr_pcl { + QCA_WLAN_VENDOR_ATTR_PCL_INVALID = 0, + + /* Channel number (u8) */ + QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL = 1, + /* Channel weightage (u8) */ + QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT = 2, + /* Channel frequency (u32) in MHz */ + QCA_WLAN_VENDOR_ATTR_PCL_FREQ = 3, + /* Channel flags (u32) + * bit 0 set: channel to be used for GO role, + * bit 1 set: channel to be used on CLI role, + * bit 2 set: channel must be considered for operating channel + * selection & peer chosen operating channel should be + * one of the channels with this flag set, + * bit 3 set: channel should be excluded in GO negotiation + */ + QCA_WLAN_VENDOR_ATTR_PCL_FLAG = 4, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PCL_LAST, + QCA_WLAN_VENDOR_ATTR_PCL_MAX = QCA_WLAN_VENDOR_ATTR_PCL_LAST - 1 +}; + +/** + * qca_wlan_vendor_attr_external_acs_event: Attribute to vendor sub-command + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This attribute will be sent by + * host driver. + */ +enum qca_wlan_vendor_attr_external_acs_event { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_INVALID = 0, + + /* This reason (u8) refers to enum qca_wlan_vendor_acs_select_reason. + * This helps ACS module to understand why ACS needs to be started. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON = 1, + /* Flag attribute to indicate if driver supports spectral scanning */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_SPECTRAL_SUPPORTED = 2, + /* Flag attribute to indicate if 11ac is offloaded to firmware */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_OFFLOAD_ENABLED = 3, + /* Flag attribute to indicate if driver provides additional channel + * capability as part of scan operation + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_ADD_CHAN_STATS_SUPPORT = 4, + /* Flag attribute to indicate interface status is UP */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AP_UP = 5, + /* Operating mode (u8) of interface. Takes one of enum nl80211_iftype + * values. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_SAP_MODE = 6, + /* Channel width (u8). It takes one of enum nl80211_chan_width values. + * This is the upper bound of channel width. ACS logic should try to get + * a channel with the specified width and if not found, look for lower + * values. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_WIDTH = 7, + /* This (u8) will hold values of one of enum nl80211_bands */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_BAND = 8, + /* PHY/HW mode (u8). Takes one of enum qca_wlan_vendor_acs_hw_mode + * values + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PHY_MODE = 9, + /* Array of (u32) supported frequency list among which ACS should choose + * best frequency. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_FREQ_LIST = 10, + /* Preferred channel list by the driver which will have array of nested + * values as per enum qca_wlan_vendor_attr_pcl attribute. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL = 11, + /* Array of nested attribute for each channel. It takes attr as defined + * in enum qca_wlan_vendor_external_acs_event_chan_info_attr. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO = 12, + /* External ACS policy such as PCL mandatory, PCL preferred, etc. + * It uses values defined in enum + * qca_wlan_vendor_attr_external_acs_policy. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY = 13, + /* Reference RF Operating Parameter (RROP) availability information + * (u16). It uses values defined in enum + * qca_wlan_vendor_attr_rropavail_info. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_RROPAVAIL_INFO = 14, + /* Flag attribute to indicate if driver supports 6 GHz AFC trigger + * for External ACS + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AFC_CAPABILITY = 15, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_MAX = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_external_acs_channels: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This carries a list of channels + * in priority order as decided after ACS operation in userspace. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON: Required (u8). + * One of reason code from enum qca_wlan_vendor_acs_select_reason. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST: Required + * Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY: Required (u8). + * Primary channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY: Required (u8). + * Secondary channel number, required only for 160 and 80+80 MHz bandwidths. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0: Required (u8). + * VHT seg0 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1: Required (u8). + * VHT seg1 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH: Required (u8). + * Takes one of enum nl80211_chan_width values. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST: Required + * Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY: Required (u32) + * Primary channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY: Required (u32) + * Secondary channel frequency in MHz used for HT 40 MHz channels. + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0: Required (u32) + * VHT seg0 channel frequency in MHz + * Note: If user-space application has no support of the 6GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1: Required (u32) + * VHT seg1 channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + */ +enum qca_wlan_vendor_attr_external_acs_channels { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_INVALID = 0, + + /* One of reason code (u8) from enum qca_wlan_vendor_acs_select_reason + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON = 1, + + /* Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST = 2, + /* This (u8) will hold values of one of enum nl80211_bands */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND = 3, + /* Primary channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY = 4, + /* Secondary channel (u8) used for HT 40 MHz channels */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY = 5, + /* VHT seg0 channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 = 6, + /* VHT seg1 channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 = 7, + /* Channel width (u8). Takes one of enum nl80211_chan_width values. */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH = 8, + + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST = 9, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY = 10, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY = 11, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 = 12, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 = 13, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST - 1 +}; + +enum qca_chip_power_save_failure_reason { + /* Indicates if the reason for the failure is due to a protocol + * layer/module. + */ + QCA_CHIP_POWER_SAVE_FAILURE_REASON_PROTOCOL = 0, + /* Indicates if the reason for the failure is due to a hardware issue. + */ + QCA_CHIP_POWER_SAVE_FAILURE_REASON_HARDWARE = 1, +}; + +/** + * qca_attr_chip_power_save_failure: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE. This carries the requisite + * information leading to the power save failure. + */ +enum qca_attr_chip_power_save_failure { + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_INVALID = 0, + /* Reason to cause the power save failure. + * These reasons are represented by + * enum qca_chip_power_save_failure_reason. + */ + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON = 1, + + /* keep last */ + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST, + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_MAX = + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST - 1, +}; + +/** + * qca_wlan_vendor_nud_stats_data_pkt_flags: Flag representing the various + * data types for which the stats have to get collected. + */ +enum qca_wlan_vendor_nud_stats_data_pkt_flags { + QCA_WLAN_VENDOR_NUD_STATS_DATA_ARP = 1 << 0, + QCA_WLAN_VENDOR_NUD_STATS_DATA_DNS = 1 << 1, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_HANDSHAKE = 1 << 2, + QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV4 = 1 << 3, + QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV6 = 1 << 4, + /* Used by QCA_ATTR_NUD_STATS_PKT_TYPE only in nud stats get + * to represent the stats of respective data type. + */ + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN = 1 << 5, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN_ACK = 1 << 6, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_ACK = 1 << 7, +}; + +enum qca_wlan_vendor_nud_stats_set_data_pkt_info { + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_INVALID = 0, + /* Represents the data packet type to be monitored (u32). + * Host driver tracks the stats corresponding to each data frame + * represented by these flags. + * These data packets are represented by + * enum qca_wlan_vendor_nud_stats_data_pkt_flags + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE = 1, + /* Name corresponding to the DNS frame for which the respective DNS + * stats have to get monitored (string). Max string length 255. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME = 2, + /* source port on which the respective proto stats have to get + * collected (u32). + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT = 3, + /* destination port on which the respective proto stats have to get + * collected (u32). + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT = 4, + /* IPv4 address for which the destined data packets have to be + * monitored. (in network byte order), u32. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4 = 5, + /* IPv6 address for which the destined data packets have to be + * monitored. (in network byte order), 16 bytes array. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6 = 6, + + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST, + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_MAX = + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_nud_stats_set: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET. This carries the requisite + * information to start/stop the NUD statistics collection. + */ +enum qca_attr_nud_stats_set { + QCA_ATTR_NUD_STATS_SET_INVALID = 0, + + /* Flag to start/stop the NUD statistics collection. + * Start - If included, Stop - If not included + */ + QCA_ATTR_NUD_STATS_SET_START = 1, + /* IPv4 address of the default gateway (in network byte order), u32 */ + QCA_ATTR_NUD_STATS_GW_IPV4 = 2, + /* Represents the list of data packet types to be monitored. + * Host driver tracks the stats corresponding to each data frame + * represented by these flags. + * These data packets are represented by + * enum qca_wlan_vendor_nud_stats_set_data_pkt_info + */ + QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO = 3, + + /* keep last */ + QCA_ATTR_NUD_STATS_SET_LAST, + QCA_ATTR_NUD_STATS_SET_MAX = + QCA_ATTR_NUD_STATS_SET_LAST - 1, +}; + +enum qca_attr_nud_data_stats { + QCA_ATTR_NUD_DATA_STATS_INVALID = 0, + /* Data packet type for which the stats are collected (u32). + * Represented by enum qca_wlan_vendor_nud_stats_data_pkt_flags + */ + QCA_ATTR_NUD_STATS_PKT_TYPE = 1, + /* Name corresponding to the DNS frame for which the respective DNS + * stats are monitored (string). Max string length 255. + */ + QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME = 2, + /* source port on which the respective proto stats are collected (u32). + */ + QCA_ATTR_NUD_STATS_PKT_SRC_PORT = 3, + /* destination port on which the respective proto stats are collected + * (u32). + */ + QCA_ATTR_NUD_STATS_PKT_DEST_PORT = 4, + /* IPv4 address for which the destined data packets have to be + * monitored. (in network byte order), u32. + */ + QCA_ATTR_NUD_STATS_PKT_DEST_IPV4 = 5, + /* IPv6 address for which the destined data packets have to be + * monitored. (in network byte order), 16 bytes array. + */ + QCA_ATTR_NUD_STATS_PKT_DEST_IPV6 = 6, + /* Data packet Request count received from netdev (u32). */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV = 7, + /* Data packet Request count sent to lower MAC from upper MAC (u32). */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC = 8, + /* Data packet Request count received by lower MAC from upper MAC + * (u32) + */ + QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC = 9, + /* Data packet Request count successfully transmitted by the device + * (u32) + */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS = 10, + /* Data packet Response count received by lower MAC (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC = 11, + /* Data packet Response count received by upper MAC (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC = 12, + /* Data packet Response count delivered to netdev (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV = 13, + /* Data Packet Response count that are dropped out of order (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP = 14, + + /* keep last */ + QCA_ATTR_NUD_DATA_STATS_LAST, + QCA_ATTR_NUD_DATA_STATS_MAX = + QCA_ATTR_NUD_DATA_STATS_LAST - 1, +}; + +/** + * qca_attr_nud_stats_get: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET. This carries the requisite + * NUD statistics collected when queried. + */ +enum qca_attr_nud_stats_get { + QCA_ATTR_NUD_STATS_GET_INVALID = 0, + /* ARP Request count from netdev (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV = 1, + /* ARP Request count sent to lower MAC from upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC = 2, + /* ARP Request count received by lower MAC from upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC = 3, + /* ARP Request count successfully transmitted by the device (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS = 4, + /* ARP Response count received by lower MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC = 5, + /* ARP Response count received by upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC = 6, + /* ARP Response count delivered to netdev (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV = 7, + /* ARP Response count dropped due to out of order reception (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP = 8, + /* Flag indicating if the station's link to the AP is active. + * Active Link - If included, Inactive link - If not included + */ + QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE = 9, + /* Flag indicating if there is any duplicate address detected (DAD). + * Yes - If detected, No - If not detected. + */ + QCA_ATTR_NUD_STATS_IS_DAD = 10, + /* List of Data packet types for which the stats are requested. + * This list does not carry ARP stats as they are done by the + * above attributes. Represented by enum qca_attr_nud_data_stats. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_STATS = 11, + + /* keep last */ + QCA_ATTR_NUD_STATS_GET_LAST, + QCA_ATTR_NUD_STATS_GET_MAX = + QCA_ATTR_NUD_STATS_GET_LAST - 1, +}; + +enum qca_wlan_btm_candidate_status { + QCA_STATUS_ACCEPT = 0, + QCA_STATUS_REJECT_EXCESSIVE_FRAME_LOSS_EXPECTED = 1, + QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED = 2, + QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY = 3, + QCA_STATUS_REJECT_LOW_RSSI = 4, + QCA_STATUS_REJECT_HIGH_INTERFERENCE = 5, + QCA_STATUS_REJECT_UNKNOWN = 6, +}; + +enum qca_wlan_vendor_attr_btm_candidate_info { + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_INVALID = 0, + + /* 6-byte MAC address representing the BSSID of transition candidate */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID = 1, + /* Unsigned 32-bit value from enum qca_wlan_btm_candidate_status + * returned by the driver. It says whether the BSSID provided in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID is acceptable by + * the driver, if not it specifies the reason for rejection. + * Note that the user-space can overwrite the transition reject reason + * codes provided by driver based on more information. + */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_AFTER_LAST - 1, +}; + +enum qca_attr_trace_level { + QCA_ATTR_TRACE_LEVEL_INVALID = 0, + /* + * Nested array of the following attributes: + * QCA_ATTR_TRACE_LEVEL_MODULE, + * QCA_ATTR_TRACE_LEVEL_MASK. + */ + QCA_ATTR_TRACE_LEVEL_PARAM = 1, + /* + * Specific QCA host driver module. Please refer to the QCA host + * driver implementation to get the specific module ID. + */ + QCA_ATTR_TRACE_LEVEL_MODULE = 2, + /* Different trace level masks represented in the QCA host driver. */ + QCA_ATTR_TRACE_LEVEL_MASK = 3, + + /* keep last */ + QCA_ATTR_TRACE_LEVEL_AFTER_LAST, + QCA_ATTR_TRACE_LEVEL_MAX = + QCA_ATTR_TRACE_LEVEL_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_he_capabilities - IEEE 802.11ax HE capabilities + */ +enum qca_wlan_vendor_attr_get_he_capabilities { + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_INVALID = 0, + /* Whether HE capabilities is supported + * (u8 attribute: 0 = not supported, 1 = supported) + */ + QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED = 1, + /* HE PHY capabilities, array of 3 u32 values */ + QCA_WLAN_VENDOR_ATTR_PHY_CAPAB = 2, + /* HE MAC capabilities (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_MAC_CAPAB = 3, + /* HE MCS map (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_HE_MCS = 4, + /* Number of SS (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_NUM_SS = 5, + /* RU count (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_RU_IDX_MASK = 6, + /* PPE threshold data, array of 8 u32 values */ + QCA_WLAN_VENDOR_ATTR_PPE_THRESHOLD = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_MAX = + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_scan - Spectral scan config parameters + */ +enum qca_wlan_vendor_attr_spectral_scan { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INVALID = 0, + /* Number of times the chip enters spectral scan mode before + * deactivating spectral scans. When set to 0, chip will enter spectral + * scan mode continuously. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT = 1, + /* Spectral scan period. Period increment resolution is 256*Tclk, + * where Tclk = 1/44 MHz (Gmode), 1/40 MHz (Amode). u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD = 2, + /* Spectral scan priority. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY = 3, + /* Number of FFT data points to compute. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE = 4, + /* Enable targeted gain change before starting the spectral scan FFT. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA = 5, + /* Restart a queued spectral scan. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA = 6, + /* Noise floor reference number for the calculation of bin power. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF = 7, + /* Disallow spectral scan triggers after TX/RX packets by setting + * this delay value to roughly SIFS time period or greater. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY = 8, + /* Number of strong bins (inclusive) per sub-channel, below + * which a signal is declared a narrow band tone. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR = 9, + /* Specify the threshold over which a bin is declared strong (for + * scan bandwidth analysis). u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR = 10, + /* Spectral scan report mode. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE = 11, + /* RSSI report mode, if the ADC RSSI is below + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR, + * then FFTs will not trigger, but timestamps and summaries get + * reported. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE = 12, + /* ADC RSSI must be greater than or equal to this threshold (signed dB) + * to ensure spectral scan reporting with normal error code. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR = 13, + /* Format of frequency bin magnitude for spectral scan triggered FFTs: + * 0: linear magnitude, 1: log magnitude (20*log10(lin_mag)). + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT = 14, + /* Format of FFT report to software for spectral scan triggered FFTs. + * 0: No FFT report (only spectral scan summary report) + * 1: 2-dword summary of metrics for each completed FFT + spectral scan + * report + * 2: 2-dword summary of metrics for each completed FFT + 1x-oversampled + * bins (in-band) per FFT + spectral scan summary report + * 3: 2-dword summary of metrics for each completed FFT + 2x-oversampled + * bins (all) per FFT + spectral scan summary report + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE = 15, + /* Number of LSBs to shift out in order to scale the FFT bins. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE = 16, + /* Set to 1 (with spectral_scan_pwr_format=1), to report bin magnitudes + * in dBm power. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ = 17, + /* Per chain enable mask to select input ADC for search FFT. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK = 18, + /* An unsigned 64-bit integer provided by host driver to identify the + * spectral scan request. This attribute is included in the scan + * response message for @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START + * and used as an attribute in + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP to identify the + * specific scan to be stopped. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE = 19, + /* Skip interval for FFT reports. u32 attribute */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD = 20, + /* Set to report only one set of FFT results. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT = 21, + /* Debug level for spectral module in driver. + * 0 : Verbosity level 0 + * 1 : Verbosity level 1 + * 2 : Verbosity level 2 + * 3 : Matched filterID display + * 4 : One time dump of FFT report + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL = 22, + /* Type of spectral scan request. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_attr_spectral_scan_request_type. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE = 23, + /* This specifies the frequency span over which spectral + * scan would be carried out. Its value depends on the + * value of QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE and + * the relation is as follows. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL + * Not applicable. Spectral scan would happen in the + * operating span. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE + * Center frequency (in MHz) of the span of interest or + * for convenience, center frequency (in MHz) of any channel + * in the span of interest. For 80+80 MHz agile spectral scan + * request it represents center frequency (in MHz) of the primary + * 80 MHz span or for convenience, center frequency (in MHz) of any + * channel in the primary 80 MHz span. If agile spectral scan is + * initiated without setting a valid frequency it returns the + * error code + * (QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED). + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY = 24, + /* Spectral scan mode. u32 attribute. + * It uses values defined in enum qca_wlan_vendor_spectral_scan_mode. + * If this attribute is not present, it is assumed to be + * normal mode (QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL). + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE = 25, + /* Spectral scan error code. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_error_code. + * This attribute is included only in failure scenarios. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE = 26, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA ring. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG = 27, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA buffers. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG = 28, + /* This specifies the frequency span over which spectral scan would be + * carried out. Its value depends on the value of + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE and the relation is as + * follows. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL + * Not applicable. Spectral scan would happen in the operating span. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE + * This attribute is applicable only for agile spectral scan + * requests in 80+80 MHz mode. It represents center frequency (in + * MHz) of the secondary 80 MHz span or for convenience, center + * frequency (in MHz) of any channel in the secondary 80 MHz span. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29, + /* This attribute specifies the bandwidth to be used for spectral scan + * operation. This is an u8 attribute and uses the values in enum + * nl80211_chan_width. This is an optional attribute. + * If this attribute is not populated, the driver should configure the + * spectral scan bandwidth to the maximum value supported by the target + * for the current operating bandwidth. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30, + /* Spectral FFT recapture flag attribute, to enable FFT recapture. + * Recapture can only be enabled for scan period greater than 52 us. + * If this attribute is enabled, re-triggers will be enabled when AGC + * gain changes. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_RECAPTURE = 31, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_diag_stats - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS. + */ +enum qca_wlan_vendor_attr_spectral_diag_stats { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_INVALID = 0, + /* Number of spectral TLV signature mismatches. + * u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SIG_MISMATCH = 1, + /* Number of spectral phyerror events with insufficient length when + * parsing for secondary 80 search FFT report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SEC80_SFFT_INSUFFLEN = 2, + /* Number of spectral phyerror events without secondary 80 + * search FFT report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_NOSEC80_SFFT = 3, + /* Number of spectral phyerror events with vht operation segment 1 id + * mismatches in search fft report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG1ID_MISMATCH = 4, + /* Number of spectral phyerror events with vht operation segment 2 id + * mismatches in search fft report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH = 5, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_cap - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. + */ +enum qca_wlan_vendor_attr_spectral_cap { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_INVALID = 0, + /* Flag attribute to indicate phydiag capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_PHYDIAG = 1, + /* Flag attribute to indicate radar detection capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RADAR = 2, + /* Flag attribute to indicate spectral capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_SPECTRAL = 3, + /* Flag attribute to indicate advanced spectral capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_ADVANCED_SPECTRAL = 4, + /* Spectral hardware generation. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_cap_hw_gen. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN = 5, + /* Spectral bin scaling formula ID. u16 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_cap_formula_id. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID = 6, + /* Spectral bin scaling param - low level offset. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET = 7, + /* Spectral bin scaling param - high level offset. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET = 8, + /* Spectral bin scaling param - RSSI threshold. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR = 9, + /* Spectral bin scaling param - default AGC max gain. + * u8 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN = 10, + /* Flag attribute to indicate agile spectral scan capability + * for 20/40/80 MHz modes. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL = 11, + /* Flag attribute to indicate agile spectral scan capability + * for 160 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_160 = 12, + /* Flag attribute to indicate agile spectral scan capability + * for 80+80 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_80_80 = 13, + /* Number of spectral detectors used for scan in 20 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_20_MHZ = 14, + /* Number of spectral detectors used for scan in 40 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_40_MHZ = 15, + /* Number of spectral detectors used for scan in 80 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80_MHZ = 16, + /* Number of spectral detectors used for scan in 160 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_160_MHZ = 17, + /* Number of spectral detectors used for scan in 80+80 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18, + /* Flag attribute to indicate agile spectral scan capability + * for 320 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19, + /* Number of spectral detectors used for scan in 320 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_scan_status - used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS. + */ +enum qca_wlan_vendor_attr_spectral_scan_status { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_INVALID = 0, + /* Flag attribute to indicate whether spectral scan is enabled */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ENABLED = 1, + /* Flag attribute to indicate whether spectral scan is in progress*/ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE = 2, + /* Spectral scan mode. u32 attribute. + * It uses values defined in enum qca_wlan_vendor_spectral_scan_mode. + * If this attribute is not present, normal mode + * (QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL is assumed to be + * requested. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE = 3, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_spectral_scan_request_type: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START. This represents the + * spectral scan request types. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN_AND_CONFIG: Request to + * set the spectral parameters and start scan. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN: Request to + * only set the spectral parameters. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_CONFIG: Request to + * only start the spectral scan. + */ +enum qca_wlan_vendor_attr_spectral_scan_request_type { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN_AND_CONFIG, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_CONFIG, +}; + +/** + * qca_wlan_vendor_spectral_scan_mode: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START and + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS. This represents the + * spectral scan modes. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL: Normal spectral scan: + * spectral scan in the current operating span. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE: Agile spectral scan: + * spectral scan in the configured agile span. + */ +enum qca_wlan_vendor_spectral_scan_mode { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE = 1, +}; + +/** + * qca_wlan_vendor_spectral_scan_error_code: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED: Changing the value + * of a parameter is not supported. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED: Requested spectral scan + * mode is not supported. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE: A parameter + * has invalid value. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED: A parameter + * is not initialized. + */ +enum qca_wlan_vendor_spectral_scan_error_code { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED = 1, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE = 2, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED = 3, +}; + +/** + * qca_wlan_vendor_spectral_scan_cap_hw_gen: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. This represents the + * spectral hardware generation. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_1: generation 1 + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_2: generation 2 + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_3: generation 3 + */ +enum qca_wlan_vendor_spectral_scan_cap_hw_gen { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_1 = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_2 = 1, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_3 = 2, +}; + +enum qca_wlan_vendor_tos { + QCA_WLAN_VENDOR_TOS_BK = 0, + QCA_WLAN_VENDOR_TOS_BE = 1, + QCA_WLAN_VENDOR_TOS_VI = 2, + QCA_WLAN_VENDOR_TOS_VO = 3, +}; + +/** + * enum qca_wlan_vendor_attr_active_tos - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS. + */ +enum qca_wlan_vendor_attr_active_tos { + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_INVALID = 0, + /* Type Of Service - Represented by qca_wlan_vendor_tos */ + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS = 1, + /* Flag attribute representing the start (attribute included) or stop + * (attribute not included) of the respective TOS. + */ + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START = 2, +}; + +enum qca_wlan_vendor_hang_reason { + /* Unspecified reason */ + QCA_WLAN_HANG_REASON_UNSPECIFIED = 0, + /* No Map for the MAC entry for the received frame */ + QCA_WLAN_HANG_RX_HASH_NO_ENTRY_FOUND = 1, + /* Peer deletion timeout happened */ + QCA_WLAN_HANG_PEER_DELETION_TIMEDOUT = 2, + /* Peer unmap timeout */ + QCA_WLAN_HANG_PEER_UNMAP_TIMEDOUT = 3, + /* Scan request timed out */ + QCA_WLAN_HANG_SCAN_REQ_EXPIRED = 4, + /* Consecutive Scan attempt failures */ + QCA_WLAN_HANG_SCAN_ATTEMPT_FAILURES = 5, + /* Unable to get the message buffer */ + QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE = 6, + /* Current command processing is timedout */ + QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT = 7, + /* Timeout for an ACK from FW for suspend request */ + QCA_WLAN_HANG_SUSPEND_TIMEOUT = 8, + /* Timeout for an ACK from FW for resume request */ + QCA_WLAN_HANG_RESUME_TIMEOUT = 9, + /* Transmission timeout for consecutive data frames */ + QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT = 10, + /* Timeout for the TX completion status of data frame */ + QCA_WLAN_HANG_TX_COMPLETE_TIMEOUT = 11, + /* DXE failure for TX/RX, DXE resource unavailability */ + QCA_WLAN_HANG_DXE_FAILURE = 12, + /* WMI pending commands exceed the maximum count */ + QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS = 13, + /* Timeout for peer STA connection accept command's response from the + * FW in AP mode. This command is triggered when a STA (peer) connects + * to AP (DUT). + */ + QCA_WLAN_HANG_AP_STA_CONNECT_REQ_TIMEOUT = 14, + /* Timeout for the AP connection accept command's response from the FW + * in STA mode. This command is triggered when the STA (DUT) connects + * to an AP (peer). + */ + QCA_WLAN_HANG_STA_AP_CONNECT_REQ_TIMEOUT = 15, + /* Timeout waiting for the response to the MAC HW mode change command + * sent to FW as a part of MAC mode switch among DBS (Dual Band + * Simultaneous), SCC (Single Channel Concurrency), and MCC (Multi + * Channel Concurrency) mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CHANGE_TIMEOUT = 16, + /* Timeout waiting for the response from FW to configure the MAC HW's + * mode. This operation is to configure the single/two MACs in either + * SCC/MCC/DBS mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CONFIG_TIMEOUT = 17, + /* Timeout waiting for response of VDEV start command from the FW */ + QCA_WLAN_HANG_VDEV_START_RESPONSE_TIMED_OUT = 18, + /* Timeout waiting for response of VDEV restart command from the FW */ + QCA_WLAN_HANG_VDEV_RESTART_RESPONSE_TIMED_OUT = 19, + /* Timeout waiting for response of VDEV stop command from the FW */ + QCA_WLAN_HANG_VDEV_STOP_RESPONSE_TIMED_OUT = 20, + /* Timeout waiting for response of VDEV delete command from the FW */ + QCA_WLAN_HANG_VDEV_DELETE_RESPONSE_TIMED_OUT = 21, + /* Timeout waiting for response of peer all delete request command to + * the FW on a specific VDEV. + */ + QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22, + /* WMI sequence mismatch between WMI command and Tx completion */ + QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23, + /* Write to Device HAL register failed */ + QCA_WLAN_HANG_REG_WRITE_FAILURE = 24, + /* No credit left to send the wow_wakeup_from_sleep to firmware */ + QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25, + /* Bus failure */ + QCA_WLAN_HANG_BUS_FAILURE = 26, + /* tasklet/credit latency found */ + QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27, +}; + +/** + * enum qca_wlan_vendor_attr_hang - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_HANG. + */ +enum qca_wlan_vendor_attr_hang { + QCA_WLAN_VENDOR_ATTR_HANG_INVALID = 0, + /* Reason for the hang - u32 attribute with a value from enum + * qca_wlan_vendor_hang_reason. + */ + QCA_WLAN_VENDOR_ATTR_HANG_REASON = 1, + /* The binary blob data associated with the hang reason specified by + * QCA_WLAN_VENDOR_ATTR_HANG_REASON. This binary data is expected to + * contain the required dump to analyze the reason for the hang. + * NLA_BINARY attribute, the max size is 1024 bytes. + */ + QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA = 2, + + QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HANG_MAX = + QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_flush_pending_policy: Represents values for + * the policy to flush pending frames, configured via + * %QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING. This enumeration defines the + * valid values for %QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY. + * + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE: This value clears all + * the flush policy configured before. This command basically disables the + * flush config set by the user. + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE: This value configures + * the flush policy to be immediate. All pending packets for the peer/TID are + * flushed when this command/policy is received. + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END: This value configures + * the flush policy to the end of TWT SP. All pending packets for the peer/TID + * are flushed when the end of TWT SP is reached. + */ +enum qca_wlan_vendor_flush_pending_policy { + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE = 0, + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE = 1, + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END = 2, +}; + +/** + * enum qca_wlan_vendor_attr_flush_pending - Attributes for + * flushing pending traffic in firmware. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_ADDR: Configure peer MAC address. + * @QCA_WLAN_VENDOR_ATTR_AC: Configure access category of the pending + * packets. It is u8 value with bit 0~3 represent AC_BE, AC_BK, + * AC_VI, AC_VO respectively. Set the corresponding bit to 1 to + * flush packets with access category. This is optional. See below. + * @QCA_WLAN_VENDOR_ATTR_TID_MASK: Configure TID mask of the pending packets. + * It is a u32 value with bit 0-7 representing TID 0-7. Set corresponding + * bit to 1 to act upon the TID. This is optional. Either this attribute or + * %QCA_WLAN_VENDOR_ATTR_AC must be provided. If both are provided, + * %QCA_WLAN_VENDOR_ATTR_TID_MASK takes precedence. If neither are provided + * it is an error. + * @QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY: Policy of flushing the pending + * packets corresponding to the peer/TID provided. It is a u32 value, + * represented by %enum qca_wlan_vendor_flush_pending_policy. This + * value is honored only when TID mask is provided. This is not honored when AC + * mask is provided. + */ +enum qca_wlan_vendor_attr_flush_pending { + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_PEER_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_AC = 2, + QCA_WLAN_VENDOR_ATTR_TID_MASK = 3, + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_MAX = + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_spectral_scan_cap_formula_id: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. This represents the + * Spectral bin scaling formula ID. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING: No scaling + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED: AGC gain + * and RSSI threshold based formula. + */ +enum qca_wlan_vendor_spectral_scan_cap_formula_id { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_rropavail_info - Specifies whether Representative + * RF Operating Parameter (RROP) information is available, and if so, at which + * point in the application-driver interaction sequence it can be retrieved by + * the application from the driver. This point may vary by architecture and + * other factors. This is a u16 value. + */ +enum qca_wlan_vendor_attr_rropavail_info { + /* RROP information is unavailable. */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_UNAVAILABLE, + /* RROP information is available and the application can retrieve the + * information after receiving an QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS + * event from the driver. + */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_EXTERNAL_ACS_START, + /* RROP information is available only after a vendor specific scan + * (requested using QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN) has + * successfully completed. The application can retrieve the information + * after receiving the QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE event from + * the driver. + */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_VSCAN_END, +}; + +/** + * enum qca_wlan_vendor_attr_rrop_info - Specifies vendor specific + * Representative RF Operating Parameter (RROP) information. It is sent for the + * vendor command QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO. This information is + * intended for use by external Auto Channel Selection applications. It provides + * guidance values for some RF parameters that are used by the system during + * operation. These values could vary by channel, band, radio, and so on. + */ +enum qca_wlan_vendor_attr_rrop_info { + QCA_WLAN_VENDOR_ATTR_RROP_INFO_INVALID = 0, + + /* Representative Tx Power List (RTPL) which has an array of nested + * values as per attributes in enum qca_wlan_vendor_attr_rtplinst. + */ + QCA_WLAN_VENDOR_ATTR_RROP_INFO_RTPL = 1, + + QCA_WLAN_VENDOR_ATTR_RROP_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RROP_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_RROP_INFO_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_rtplinst - Specifies attributes for individual list + * entry instances in the Representative Tx Power List (RTPL). It provides + * simplified power values intended for helping external Auto channel Selection + * applications compare potential Tx power performance between channels, other + * operating conditions remaining identical. These values are not necessarily + * the actual Tx power values that will be used by the system. They are also not + * necessarily the max or average values that will be used. Instead, they are + * relative, summarized keys for algorithmic use computed by the driver or + * underlying firmware considering a number of vendor specific factors. + */ +enum qca_wlan_vendor_attr_rtplinst { + QCA_WLAN_VENDOR_ATTR_RTPLINST_INVALID = 0, + + /* Primary channel number (u8). + * Note: If both the driver and user space application support the + * 6 GHz band, this attribute is deprecated and + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY should be used. To + * maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY is still used if either the + * driver or user space application or both do not support the 6 GHz + * band. + */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY = 1, + /* Representative Tx power in dBm (s32) with emphasis on throughput. */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_THROUGHPUT = 2, + /* Representative Tx power in dBm (s32) with emphasis on range. */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_RANGE = 3, + /* Primary channel center frequency (u32) in MHz */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY = 4, + + QCA_WLAN_VENDOR_ATTR_RTPLINST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RTPLINST_MAX = + QCA_WLAN_VENDOR_ATTR_RTPLINST_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_config_latency_level - Level for + * wlan latency module. + * + * There will be various of Wi-Fi functionality like scan/roaming/adaptive + * power saving which would causing data exchange out of service, this + * would be a big impact on latency. For latency sensitive applications over + * Wi-Fi are intolerant to such operations and thus would configure them + * to meet their respective needs. It is well understood by such applications + * that altering the default behavior would degrade the Wi-Fi functionality + * w.r.t the above pointed WLAN operations. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL: + * Default WLAN operation level which throughput orientated. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR: + * Use XR level to benefit XR (extended reality) application to achieve + * latency and power by via constraint scan/roaming/adaptive PS. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW: + * Use low latency level to benefit application like concurrent + * downloading or video streaming via constraint scan/adaptive PS. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW: + * Use ultra low latency level to benefit for gaming/voice + * application via constraint scan/roaming/adaptive PS. + */ +enum qca_wlan_vendor_attr_config_latency_level { + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR = 2, + /* legacy name */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW = 3, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_wlan_mac - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO. + */ +enum qca_wlan_vendor_attr_mac { + QCA_WLAN_VENDOR_ATTR_MAC_INVALID = 0, + + /* MAC mode info list which has an array of nested values as + * per attributes in enum qca_wlan_vendor_attr_mac_mode_info. + */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mac_iface_info - Information of the connected + * Wi-Fi netdev interface on a respective MAC. + * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO. + */ +enum qca_wlan_vendor_attr_mac_iface_info { + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_INVALID = 0, + /* Wi-Fi netdev's interface index (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX = 1, + /* Associated frequency in MHz of the connected Wi-Fi interface (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mac_info - Points to MAC the information. + * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_INFO of the + * vendor command QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO. + */ +enum qca_wlan_vendor_attr_mac_info { + QCA_WLAN_VENDOR_ATTR_MAC_INFO_INVALID = 0, + /* Hardware MAC ID associated for the MAC (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID = 1, + /* Band supported by the MAC at a given point. + * This is a u32 bitmask of BIT(NL80211_BAND_*) as described in %enum + * nl80211_band. + */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND = 2, + /* Refers to list of WLAN netdev interfaces associated with this MAC. + * Represented by enum qca_wlan_vendor_attr_mac_iface_info. + */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_logger_features - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET. + */ +enum qca_wlan_vendor_attr_get_logger_features { + QCA_WLAN_VENDOR_ATTR_LOGGER_INVALID = 0, + /* Unsigned 32-bit enum value of wifi_logger_supported_features */ + QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOGGER_MAX = + QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST - 1, +}; + +/** + * enum wifi_logger_supported_features - Values for supported logger features + */ +enum wifi_logger_supported_features { + WIFI_LOGGER_MEMORY_DUMP_FEATURE = (1 << (0)), + WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_FEATURE = (1 << (1)), + WIFI_LOGGER_CONNECT_EVENT_FEATURE = (1 << (2)), + WIFI_LOGGER_POWER_EVENT_FEATURE = (1 << (3)), + WIFI_LOGGER_WAKE_LOCK_FEATURE = (1 << (4)), + WIFI_LOGGER_VERBOSE_FEATURE = (1 << (5)), + WIFI_LOGGER_WATCHDOG_TIMER_FEATURE = (1 << (6)), + WIFI_LOGGER_DRIVER_DUMP_FEATURE = (1 << (7)), + WIFI_LOGGER_PACKET_FATE_FEATURE = (1 << (8)), +}; + +/** + * enum qca_wlan_tdls_caps_features_supported - Values for TDLS get + * capabilities features + */ +enum qca_wlan_tdls_caps_features_supported { + WIFI_TDLS_SUPPORT = (1 << (0)), + WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT = (1 << (1)), + WIFI_TDLS_OFFCHANNEL_SUPPORT = (1 << (2)) +}; + +/** + * enum qca_wlan_vendor_attr_tdls_get_capabilities - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES. + */ +enum qca_wlan_vendor_attr_tdls_get_capabilities { + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_INVALID = 0, + /* Indicates the max concurrent sessions */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS, + /* Indicates the support for features */ + /* Unsigned 32-bit bitmap qca_wlan_tdls_caps_features_supported + */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_offloaded_packets_sending_control - Offload packets control + * command used as value for the attribute + * QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL. + */ +enum qca_wlan_offloaded_packets_sending_control { + QCA_WLAN_OFFLOADED_PACKETS_SENDING_CONTROL_INVALID = 0, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_START, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_STOP +}; + +/** + * enum qca_wlan_vendor_attr_offloaded_packets - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS. + */ +enum qca_wlan_vendor_attr_offloaded_packets { + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_INVALID = 0, + /* Takes valid value from the enum + * qca_wlan_offloaded_packets_sending_control + * Unsigned 32-bit value + */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID, + /* array of u8 len: Max packet size */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA, + /* 6-byte MAC address used to represent source MAC address */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR, + /* 6-byte MAC address used to represent destination MAC address */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR, + /* Unsigned 32-bit value, in milli seconds */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD, + /* This optional unsigned 16-bit attribute is used for specifying + * ethernet protocol type. If not specified ethertype defaults to IPv4. + */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_ETHER_PROTO_TYPE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX = + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_rssi_monitoring_control - RSSI control commands used as values + * by the attribute QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL. + */ +enum qca_wlan_rssi_monitoring_control { + QCA_WLAN_RSSI_MONITORING_CONTROL_INVALID = 0, + QCA_WLAN_RSSI_MONITORING_START, + QCA_WLAN_RSSI_MONITORING_STOP, +}; + +/** + * enum qca_wlan_vendor_attr_rssi_monitoring - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI. + */ +enum qca_wlan_vendor_attr_rssi_monitoring { + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_INVALID = 0, + /* Takes valid value from the enum + * qca_wlan_rssi_monitoring_control + * Unsigned 32-bit value enum qca_wlan_rssi_monitoring_control + */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + /* Signed 8-bit value in dBm */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI, + /* Signed 8-bit value in dBm */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI, + /* attributes to be used/received in callback */ + /* 6-byte MAC address used to represent current BSSID MAC address */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, + /* Signed 8-bit value indicating the current RSSI */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX = + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ndp_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_NDP. + */ +enum qca_wlan_vendor_attr_ndp_params { + QCA_WLAN_VENDOR_ATTR_NDP_PARAM_INVALID = 0, + /* Unsigned 32-bit value + * enum of sub commands values in qca_wlan_ndp_sub_cmd + */ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + /* NL attributes for data used NDP SUB cmds */ + /* Unsigned 32-bit value indicating a service info */ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + /* Interface Discovery MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + /* Interface name on which NDP is being created */ + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + /* Unsigned 32-bit value for security */ + /* CONFIG_SECURITY is deprecated, use NCS_SK_TYPE/PMK/SCID instead */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, + /* Unsigned 32-bit value for QoS */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, + /* Array of u8: len = QCA_WLAN_VENDOR_ATTR_NAN_DP_APP_INFO_LEN */ + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + /* Unsigned 32-bit value for NDP instance Id */ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + /* Array of instance Ids */ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + /* Unsigned 32-bit value for initiator/responder NDP response code + * accept/reject + */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + /* NDI MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + /* Unsigned 32-bit value errors types returned by driver + * The wifi_nan.h in AOSP project platform/hardware/libhardware_legacy + * NanStatusType includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + /* Unsigned 32-bit value error values returned by driver + * The nan_i.h in AOSP project platform/hardware/qcom/wlan + * NanInternalStatusType includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + /* Unsigned 32-bit value for Channel setup configuration + * The wifi_nan.h in AOSP project platform/hardware/libhardware_legacy + * NanDataPathChannelCfg includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG, + /* Unsigned 32-bit value for Cipher Suite Shared Key Type */ + QCA_WLAN_VENDOR_ATTR_NDP_CSID, + /* Array of u8: len = NAN_PMK_INFO_LEN 32 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_PMK, + /* Security Context Identifier that contains the PMKID + * Array of u8: len = NAN_SCID_BUF_LEN 1024 bytes + */ + QCA_WLAN_VENDOR_ATTR_NDP_SCID, + /* Array of u8: len = NAN_SECURITY_MAX_PASSPHRASE_LEN 63 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + /* Array of u8: len = NAN_MAX_SERVICE_NAME_LEN 255 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, + /* Unsigned 32-bit bitmap indicating schedule update + * BIT_0: NSS Update + * BIT_1: Channel list update + */ + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON, + /* Unsigned 32-bit value for NSS */ + QCA_WLAN_VENDOR_ATTR_NDP_NSS, + /* Unsigned 32-bit value for NUMBER NDP CHANNEL */ + QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, + /* Unsigned 32-bit value for CHANNEL BANDWIDTH + * 0:20 MHz, 1:40 MHz, 2:80 MHz, 3:160 MHz + */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, + /* Array of channel/band width */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO, + /* IPv6 address used by NDP (in network byte order), 16 bytes array. + * This attribute is used and optional for ndp request, ndp response, + * ndp indication, and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR = 27, + /* Unsigned 16-bit value indicating transport port used by NDP. + * This attribute is used and optional for ndp response, ndp indication, + * and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT = 28, + /* Unsigned 8-bit value indicating protocol used by NDP and assigned by + * the Internet Assigned Numbers Authority (IANA) as per: + * https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + * This attribute is used and optional for ndp response, ndp indication, + * and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL = 29, + /* Unsigned 8-bit value indicating if NDP remote peer supports NAN NDPE. + * 1:support 0:not support + */ + QCA_WLAN_VENDOR_ATTR_PEER_NDPE_SUPPORT = 30, + /* As per Wi-Fi Aware Specification v3.2 Service Id is the first + * 48 bits of the SHA-256 hash of the Service Name. + * A lower-case representation of the Service Name shall be used to + * calculate the Service ID. + * Array of u8: length is 6 bytes + * This attribute is used and optional for ndp indication. + */ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID = 31, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST - 1, +}; + +enum qca_wlan_ndp_sub_cmd { + QCA_WLAN_VENDOR_ATTR_NDP_INVALID = 0, + /* Command to create a NAN data path interface. + * This command was initially designed to both create and start a NAN + * data path interface. However, changes to Linux 5.12 no longer allow + * interface creation via vendor commands. When the driver advertises + * QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI + * userspace must explicitly first create the interface using + * NL80211_CMD_NEW_INTERFACE before subsequently invoking this command + * to start the interface. + */ + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE = 1, + /* Command to delete a NAN data path interface. + * This command was initially designed to both stop and delete a NAN + * data path interface. However, changes to Linux 5.12 no longer allow + * interface deletion via vendor commands. When the driver advertises + * QCA_WLAN_VENDOR_FEATURE_USE_ADD_DEL_VIRTUAL_INTF_FOR_NDI + * userspace must explicitly delete the interface using + * NL80211_CMD_DEL_INTERFACE after calling this command. + */ + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE = 2, + /* Command to initiate a NAN data path session */ + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST = 3, + /* Command to notify if the NAN data path session was sent */ + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE = 4, + /* Command to respond to NAN data path session */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST = 5, + /* Command to notify on the responder about the response */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE = 6, + /* Command to initiate a NAN data path end */ + QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST = 7, + /* Command to notify the if end request was sent */ + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE = 8, + /* Command to notify the peer about the end request */ + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND = 9, + /* Command to confirm the NAN data path session is complete */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND = 10, + /* Command to indicate the peer about the end request being received */ + QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11, + /* Command to indicate the peer of schedule update */ + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND = 12 +}; + +/** + * enum qca_wlan_vendor_attr_nd_offload - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD. + */ +enum qca_wlan_vendor_attr_nd_offload { + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_INVALID = 0, + /* Flag to set Neighbour Discovery offload */ + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG, + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST - 1, +}; + +/** + * enum packet_filter_sub_cmd - Packet filter sub commands + */ +enum packet_filter_sub_cmd { + /** + * Write packet filter program and/or data. The driver/firmware should + * disable APF before writing into local buffer and re-enable APF after + * writing is done. + */ + QCA_WLAN_SET_PACKET_FILTER = 1, + /* Get packet filter feature capabilities from driver */ + QCA_WLAN_GET_PACKET_FILTER = 2, + /** + * Write packet filter program and/or data. User space will send the + * %QCA_WLAN_DISABLE_PACKET_FILTER command before issuing this command + * and will send the %QCA_WLAN_ENABLE_PACKET_FILTER afterwards. The key + * difference from that %QCA_WLAN_SET_PACKET_FILTER is the control over + * enable/disable is given to user space with this command. Also, + * user space sends the length of program portion in the buffer within + * %QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH. + */ + QCA_WLAN_WRITE_PACKET_FILTER = 3, + /* Read packet filter program and/or data */ + QCA_WLAN_READ_PACKET_FILTER = 4, + /* Enable APF feature */ + QCA_WLAN_ENABLE_PACKET_FILTER = 5, + /* Disable APF feature */ + QCA_WLAN_DISABLE_PACKET_FILTER = 6, +}; + +/** + * enum qca_wlan_vendor_attr_packet_filter - BPF control commands used by + * vendor QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER. + */ +enum qca_wlan_vendor_attr_packet_filter { + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID = 0, + /* Unsigned 32-bit enum passed using packet_filter_sub_cmd */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + /* Unsigned 32-bit value indicating the packet filter version */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION, + /* Unsigned 32-bit value indicating the packet filter id */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID, + /** + * Unsigned 32-bit value indicating the packet filter size including + * program + data. + */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + /* Unsigned 32-bit value indicating the packet filter current offset */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + /* Program and/or data in bytes */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM, + /* Unsigned 32-bit value of the length of the program section in packet + * filter buffer. + */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX = + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_drv_info - WLAN driver info used by vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE. + */ +enum qca_wlan_vendor_drv_info { + QCA_WLAN_VENDOR_ATTR_DRV_INFO_INVALID = 0, + /* Maximum Message size info between firmware & HOST + * Unsigned 32-bit value + */ + QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DRV_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_DRV_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_wake_stats - Wake lock stats used by vendor + * command QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS. + */ +enum qca_wlan_vendor_attr_wake_stats { + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_INVALID = 0, + /* Unsigned 32-bit value indicating the total count of wake event */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_CMD_EVENT_WAKE, + /* Array of individual wake count, each index representing wake reason + */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR, + /* Unsigned 32-bit value representing wake count array */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ, + /* Unsigned 32-bit total wake count value of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE, + /* Array of wake stats of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR, + /* Unsigned 32-bit total wake count value of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ, + /* Unsigned 32-bit total wake count value of packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE, + /* Unsigned 32-bit wake count value unicast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT, + /* Unsigned 32-bit wake count value multicast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value broadcast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT, + /* Unsigned 32-bit wake count value of ICMP packets */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT, + /* Unsigned 32-bit wake count value of ICMP6 packets */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT, + /* Unsigned 32-bit value ICMP6 router advertisement */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA, + /* Unsigned 32-bit value ICMP6 neighbor advertisement */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA, + /* Unsigned 32-bit value ICMP6 neighbor solicitation */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS, + /* Unsigned 32-bit wake count value of receive side ICMP4 multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of receive side ICMP6 multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of receive side multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of a given RSSI breach */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RSSI_BREACH_CNT, + /* Unsigned 32-bit wake count value of low RSSI */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_LOW_RSSI_CNT, + /* Unsigned 32-bit value GSCAN count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_GSCAN_CNT, + /* Unsigned 32-bit value PNO complete count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_PNO_COMPLETE_CNT, + /* Unsigned 32-bit value PNO match count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_PNO_MATCH_CNT, + /* keep last */ + QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX = + QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_thermal_level - Defines various thermal levels + * configured by userspace to the driver/firmware. + * The values can be encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL or + * QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL attribute. + * The driver/firmware takes actions requested by userspace such as throttling + * wifi TX etc. in order to mitigate high temperature. + * + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE: Stop/clear all throttling actions. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT: Throttle TX lightly. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE: Throttle TX moderately. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE: Throttle TX severely. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL: Critical thermal level reached. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY: Emergency thermal level reached. + */ +enum qca_wlan_vendor_thermal_level { + QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE = 0, + QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT = 1, + QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE = 2, + QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE = 3, + QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL = 4, + QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY = 5, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_cmd - Vendor subcmd attributes to set + * cmd value. Used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_cmd { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_INVALID = 0, + /* The value of command, driver will implement different operations + * according to this value. It uses values defined in + * enum qca_wlan_vendor_attr_thermal_cmd_type. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1, + /* Userspace uses this attribute to configure thermal level to the + * driver/firmware, or get thermal level from the driver/firmware. + * Used in request or response, u32 attribute, + * possible values are defined in enum qca_wlan_vendor_thermal_level. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL = 2, + /* Userspace uses this attribute to configure the time in which the + * driver/firmware should complete applying settings it received from + * userspace with QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL + * command type. Used in request, u32 attribute, value is in + * milliseconds. A value of zero indicates to apply the settings + * immediately. The driver/firmware can delay applying the configured + * thermal settings within the time specified in this attribute if + * there is any critical ongoing operation. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3, + /* Nested attribute, the driver/firmware uses this attribute to report + * thermal statistics of different thermal levels to userspace when + * requested using the + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command + * type. This attribute contains a nested array of records of thermal + * statistics of multiple levels. The attributes used inside this nested + * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST - 1 +}; + +/** + * qca_wlan_vendor_attr_thermal_cmd_type: Attribute values for + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD. This represents the + * thermal command types sent to driver. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS: Request to + * get thermal shutdown configuration parameters for display. Parameters + * responded from driver are defined in + * enum qca_wlan_vendor_attr_get_thermal_params_rsp. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE: Request to + * get temperature. Host should respond with a temperature data. It is defined + * in enum qca_wlan_vendor_attr_thermal_get_temperature. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND: Request to execute thermal + * suspend action. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME: Request to execute thermal + * resume action. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to + * the driver/firmware. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current + * thermal level from the driver/firmware. The driver should respond with a + * thermal level defined in enum qca_wlan_vendor_thermal_level. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the + * current thermal statistics from the driver/firmware. The driver should + * respond with statistics of all thermal levels encapsulated in the attribute + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear + * the current thermal statistics for all thermal levels maintained in the + * driver/firmware and start counting from zero again. + */ +enum qca_wlan_vendor_attr_thermal_cmd_type { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_get_temperature - vendor subcmd attributes + * to get chip temperature by user. + * enum values are used for NL attributes for data used by + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE command for data used + * by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_get_temperature { + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_thermal_params_rsp - vendor subcmd attributes + * to get configuration parameters of thermal shutdown feature. Enum values are + * used by QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS command for data + * used by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_get_thermal_params_rsp { + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_INVALID = 0, + /* Indicate if the thermal shutdown feature is enabled. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_EN, + /* Indicate if the auto mode is enabled. + * Enable: Driver triggers the suspend/resume action. + * Disable: User space triggers the suspend/resume action. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_AUTO_EN, + /* Thermal resume threshold (degree Celsius). Issue the resume command + * if the temperature value is lower than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_RESUME_THRESH, + /* Thermal warning threshold (degree Celsius). FW reports temperature + * to driver if it's higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_WARNING_THRESH, + /* Thermal suspend threshold (degree Celsius). Issue the suspend command + * if the temperature value is higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SUSPEND_THRESH, + /* FW reports temperature data periodically at this interval (ms). + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SAMPLE_RATE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_MAX = + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_event - vendor subcmd attributes to + * report thermal events from driver to user space. + * enum values are used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT sub command. + */ +enum qca_wlan_vendor_attr_thermal_event { + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_TEMPERATURE, + /* Indication of resume completion from power save mode. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE, + /* Thermal level from the driver. + * u32 attribute. Possible values are defined in + * enum qca_wlan_vendor_thermal_level. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes + * to get thermal status from the driver/firmware. + * enum values are used for NL attributes encapsulated inside the + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute. + * + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each + * thermal level in milliseconds. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number + * of times the temperature crossed into the temperature range defined by the + * thermal level from both higher and lower directions. u32 size. + */ +enum qca_wlan_vendor_attr_thermal_stats { + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1, +}; + +/** + * enum he_fragmentation_val - HE fragmentation support values + * Indicates level of dynamic fragmentation that is supported by + * a STA as a recipient. + * HE fragmentation values are defined in IEEE P802.11ax/D2.0, 9.4.2.237.2 + * (HE MAC Capabilities Information field) and are used in HE Capabilities + * element to advertise the support. These values are validated in the driver + * to check the device capability and advertised in the HE Capabilities + * element. These values are used to configure testbed device to allow the + * advertised hardware capabilities to be downgraded for testing purposes. + * + * @HE_FRAG_DISABLE: no support for dynamic fragmentation + * @HE_FRAG_LEVEL1: support for dynamic fragments that are + * contained within an MPDU or S-MPDU, no support for dynamic fragments + * within an A-MPDU that is not an S-MPDU. + * @HE_FRAG_LEVEL2: support for dynamic fragments that are + * contained within an MPDU or S-MPDU and support for up to one dynamic + * fragment for each MSDU, each A-MSDU if supported by the recipient, and + * each MMPDU within an A-MPDU or multi-TID A-MPDU that is not an + * MPDU or S-MPDU. + * @HE_FRAG_LEVEL3: support for dynamic fragments that are + * contained within an MPDU or S-MPDU and support for multiple dynamic + * fragments for each MSDU and for each A-MSDU if supported by the + * recipient within an A-MPDU or multi-TID AMPDU and up to one dynamic + * fragment for each MMPDU in a multi-TID A-MPDU that is not an S-MPDU. + */ +enum he_fragmentation_val { + HE_FRAG_DISABLE, + HE_FRAG_LEVEL1, + HE_FRAG_LEVEL2, + HE_FRAG_LEVEL3, +}; + +/** + * enum he_mcs_config - HE MCS support configuration + * + * Configures the HE Tx/Rx MCS map in HE capability IE for given bandwidth. + * These values are used in driver to configure the HE MCS map to advertise + * Tx/Rx MCS map in HE capability and these values are applied for all the + * streams supported by the device. To configure MCS for different bandwidths, + * vendor command needs to be sent using this attribute with appropriate value. + * For example, to configure HE_80_MCS_0_7, send vendor command using HE MCS + * attribute with HE_80_MCS0_7. And to configure HE MCS for HE_160_MCS0_11 + * send this command using HE MCS config attribute with value HE_160_MCS0_11. + * These values are used to configure testbed device to allow the advertised + * hardware capabilities to be downgraded for testing purposes. The enum values + * are defined such that BIT[1:0] indicates the MCS map value. Values 3,7 and + * 11 are not used as BIT[1:0] value is 3 which is used to disable MCS map. + * These values are validated in the driver before setting the MCS map and + * driver returns error if the input is other than these enum values. + * + * @HE_80_MCS0_7: support for HE 80/40/20 MHz MCS 0 to 7 + * @HE_80_MCS0_9: support for HE 80/40/20 MHz MCS 0 to 9 + * @HE_80_MCS0_11: support for HE 80/40/20 MHz MCS 0 to 11 + * @HE_160_MCS0_7: support for HE 160 MHz MCS 0 to 7 + * @HE_160_MCS0_9: support for HE 160 MHz MCS 0 to 9 + * @HE_160_MCS0_11: support for HE 160 MHz MCS 0 to 11 + * @HE_80P80_MCS0_7: support for HE 80p80 MHz MCS 0 to 7 + * @HE_80P80_MCS0_9: support for HE 80p80 MHz MCS 0 to 9 + * @HE_80P80_MCS0_11: support for HE 80p80 MHz MCS 0 to 11 + */ +enum he_mcs_config { + HE_80_MCS0_7 = 0, + HE_80_MCS0_9 = 1, + HE_80_MCS0_11 = 2, + HE_160_MCS0_7 = 4, + HE_160_MCS0_9 = 5, + HE_160_MCS0_11 = 6, + HE_80P80_MCS0_7 = 8, + HE_80P80_MCS0_9 = 9, + HE_80P80_MCS0_11 = 10, +}; + +/** + * enum qca_wlan_ba_session_config - BA session configuration + * + * Indicates the configuration values for BA session configuration attribute. + * + * @QCA_WLAN_ADD_BA: Establish a new BA session with given configuration. + * @QCA_WLAN_DELETE_BA: Delete the existing BA session for given TID. + */ +enum qca_wlan_ba_session_config { + QCA_WLAN_ADD_BA = 1, + QCA_WLAN_DELETE_BA = 2, +}; + +/** + * enum qca_wlan_ac_type - Access category type + * + * Indicates the access category type value. + * + * @QCA_WLAN_AC_BE: BE access category + * @QCA_WLAN_AC_BK: BK access category + * @QCA_WLAN_AC_VI: VI access category + * @QCA_WLAN_AC_VO: VO access category + * @QCA_WLAN_AC_ALL: All ACs + */ +enum qca_wlan_ac_type { + QCA_WLAN_AC_BE = 0, + QCA_WLAN_AC_BK = 1, + QCA_WLAN_AC_VI = 2, + QCA_WLAN_AC_VO = 3, + QCA_WLAN_AC_ALL = 4, +}; + +/** + * enum qca_wlan_he_ltf_cfg - HE LTF configuration + * + * Indicates the HE LTF configuration value. + * + * @QCA_WLAN_HE_LTF_AUTO: HE-LTF is automatically set to the mandatory HE-LTF, + * based on the GI setting + * @QCA_WLAN_HE_LTF_1X: 1X HE LTF is 3.2us LTF + * @QCA_WLAN_HE_LTF_2X: 2X HE LTF is 6.4us LTF + * @QCA_WLAN_HE_LTF_4X: 4X HE LTF is 12.8us LTF + */ +enum qca_wlan_he_ltf_cfg { + QCA_WLAN_HE_LTF_AUTO = 0, + QCA_WLAN_HE_LTF_1X = 1, + QCA_WLAN_HE_LTF_2X = 2, + QCA_WLAN_HE_LTF_4X = 3, +}; + +/** + * enum qca_wlan_he_mac_padding_dur - HE trigger frame MAC padding duration + * + * Indicates the HE trigger frame MAC padding duration value. + * + * @QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME: no additional time required to + * process the trigger frame. + * @QCA_WLAN_HE_8US_OF_PROCESS_TIME: indicates the 8us of processing time for + * trigger frame. + * @QCA_WLAN_HE_16US_OF_PROCESS_TIME: indicates the 16us of processing time for + * trigger frame. + */ +enum qca_wlan_he_mac_padding_dur { + QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME = 0, + QCA_WLAN_HE_8US_OF_PROCESS_TIME = 1, + QCA_WLAN_HE_16US_OF_PROCESS_TIME = 2, +}; + +/** + * enum qca_wlan_he_om_ctrl_ch_bw - HE OM control field BW configuration + * + * Indicates the HE Operating mode control channel width setting value. + * + * @QCA_WLAN_HE_OM_CTRL_BW_20M: Primary 20 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_40M: Primary 40 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_80M: Primary 80 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_160M: 160 MHz and 80+80 MHz + */ +enum qca_wlan_he_om_ctrl_ch_bw { + QCA_WLAN_HE_OM_CTRL_BW_20M = 0, + QCA_WLAN_HE_OM_CTRL_BW_40M = 1, + QCA_WLAN_HE_OM_CTRL_BW_80M = 2, + QCA_WLAN_HE_OM_CTRL_BW_160M = 3, +}; + +/** + * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration + * + * Indicates the frame types to use for keep alive data. + * + * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive. + * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive. + * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive. + */ +enum qca_wlan_keep_alive_data_type { + QCA_WLAN_KEEP_ALIVE_DEFAULT = 0, + QCA_WLAN_KEEP_ALIVE_DATA = 1, + QCA_WLAN_KEEP_ALIVE_MGMT = 2, +}; + +/** + * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for + * HE operating mode control transmit request. These attributes are + * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and + * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS: Mandatory 8-bit unsigned value + * indicates the maximum number of spatial streams, NSS, that the STA + * supports in reception for PPDU bandwidths less than or equal to 80 MHz + * and is set to NSS - 1. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW: Mandatory 8-bit unsigned value + * indicates the operating channel width supported by the STA for both + * reception and transmission. Uses enum qca_wlan_he_om_ctrl_ch_bw values. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE: Mandatory 8-bit unsigned value + * indicates the all trigger based UL MU operations by the STA. + * 0 - UL MU operations are enabled by the STA. + * 1 - All triggered UL MU transmissions are suspended by the STA. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS: Mandatory 8-bit unsigned value + * indicates the maximum number of space-time streams, NSTS, that + * the STA supports in transmission and is set to NSTS - 1. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE: 8-bit unsigned value + * combined with the UL MU Disable subfield and the recipient's setting + * of the OM Control UL MU Data Disable RX Support subfield in the HE MAC + * capabilities to determine which HE TB PPDUs are possible by the + * STA to transmit. + * 0 - UL MU data operations are enabled by the STA. + * 1 - Determine which HE TB PPDU types are allowed by the STA if UL MU disable + * bit is not set, else UL MU Tx is suspended. + * + */ +enum qca_wlan_vendor_attr_he_omi_tx { + QCA_WLAN_VENDOR_ATTR_HE_OMI_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS = 1, + QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW = 2, + QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE = 3, + QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS = 4, + QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX = + QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST - 1, +}; + + /** + * enum qca_wlan_vendor_phy_mode - Different PHY modes + * These values are used with %QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE. + * + * @QCA_WLAN_VENDOR_PHY_MODE_AUTO: autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO: 2.4 GHz 802.11b/g/n/ax autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO: 5 GHz 802.11a/n/ac/ax autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_11A: 5 GHz, OFDM + * @QCA_WLAN_VENDOR_PHY_MODE_11B: 2.4 GHz, CCK + * @QCA_WLAN_VENDOR_PHY_MODE_11G: 2.4 GHz, OFDM + * @QCA_WLAN_VENDOR_PHY_MODE_11AGN: Support 802.11n in both 2.4 GHz and 5 GHz + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20: 2.4 GHz, HT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS: 2.4 GHz, HT40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS: 2.4 GHz, HT40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40: 2.4 GHz, Auto HT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20: 5 GHz, HT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS: 5 GHz, HT40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS: 5 GHz, HT40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40: 5 GHz, Auto HT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20: 5 GHz, VHT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS: 5 GHz, VHT40 (Ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS: 5 GHz VHT40 (Ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40: 5 GHz, VHT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80: 5 GHz, VHT80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80: 5 GHz, VHT80+80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160: 5 GHz, VHT160 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20: HE20 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40: HE40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS: HE40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS: HE40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80: HE80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80: HE 80P80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160: HE160 + */ +enum qca_wlan_vendor_phy_mode { + QCA_WLAN_VENDOR_PHY_MODE_AUTO = 0, + QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO = 1, + QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO = 2, + QCA_WLAN_VENDOR_PHY_MODE_11A = 3, + QCA_WLAN_VENDOR_PHY_MODE_11B = 4, + QCA_WLAN_VENDOR_PHY_MODE_11G = 5, + QCA_WLAN_VENDOR_PHY_MODE_11AGN = 6, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20 = 7, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS = 8, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS = 9, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40 = 10, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20 = 11, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS = 12, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS = 13, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40 = 14, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20 = 15, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS = 16, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS = 17, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40 = 18, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80 = 19, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80 = 20, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160 = 21, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20 = 22, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40 = 23, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS = 24, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS = 25, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80 = 26, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80 = 27, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160 = 28, +}; + +/* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION + */ +enum qca_wlan_vendor_attr_wifi_test_config { + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_INVALID = 0, + /* 8-bit unsigned value to configure the driver to enable/disable + * WMM feature. This attribute is used to configure testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE = 1, + + /* 8-bit unsigned value to configure the driver to accept/reject + * the addba request from peer. This attribute is used to configure + * the testbed device. + * 1-accept addba, 0-reject addba + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ = 2, + + /* 8-bit unsigned value to configure the driver to send or not to + * send the addba request to peer. + * This attribute is used to configure the testbed device. + * 1-send addba, 0-do not send addba + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ = 3, + + /* 8-bit unsigned value to indicate the HE fragmentation support. + * Uses enum he_fragmentation_val values. + * This attribute is used to configure the testbed device to + * allow the advertised hardware capabilities to be downgraded + * for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION = 4, + + /* 8-bit unsigned value to indicate the HE MCS support. + * Uses enum he_mcs_config values. + * This attribute is used to configure the testbed device to + * allow the advertised hardware capabilities to be downgraded + * for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS = 5, + + /* 8-bit unsigned value to configure the driver to allow or not to + * allow the connection with WEP/TKIP in HT/VHT/HE modes. + * This attribute is used to configure the testbed device. + * 1-allow WEP/TKIP in HT/VHT/HE, 0-do not allow WEP/TKIP. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE = 6, + + /* 8-bit unsigned value to configure the driver to add a + * new BA session or delete the existing BA session for + * given TID. ADDBA command uses the buffer size and TID + * configuration if user specifies the values else default + * value for buffer size is used for all TIDs if the TID + * also not specified. For DEL_BA command TID value is + * required to process the command. + * Uses enum qca_wlan_ba_session_config values. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION = 7, + + /* 16-bit unsigned value to configure the buffer size in addba + * request and response frames. + * This attribute is used to configure the testbed device. + * The range of the value is 0 to 256. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE = 8, + + /* 8-bit unsigned value to configure the buffer size in addba + * request and response frames. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID = 9, + + /* 8-bit unsigned value to configure the no ack policy. + * To configure no ack policy, access category value is + * required to process the command. + * This attribute is used to configure the testbed device. + * 1 - enable no ack, 0 - disable no ack. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK = 10, + + /* 8-bit unsigned value to configure the AC for no ack policy + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_ac_type values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC = 11, + + /* 8-bit unsigned value to configure the HE LTF + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_he_ltf_cfg values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF = 12, + + /* 8-bit unsigned value to configure the tx beamformee. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE = 13, + + /* 8-bit unsigned value to configure the tx beamformee number + * of space-time streams. + * This attribute is used to configure the testbed device. + * The range of the value is 0 to 8. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS = 14, + + /* 8-bit unsigned value to configure the MU EDCA params for given AC + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_ac_type values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AC = 15, + + /* 8-bit unsigned value to configure the MU EDCA AIFSN for given AC + * To configure MU EDCA AIFSN value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AIFSN = 16, + + /* 8-bit unsigned value to configure the MU EDCA ECW min value for + * given AC. + * To configure MU EDCA ECW min value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_ECWMIN = 17, + + /* 8-bit unsigned value to configure the MU EDCA ECW max value for + * given AC. + * To configure MU EDCA ECW max value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_ECWMAX = 18, + + /* 8-bit unsigned value to configure the MU EDCA timer for given AC + * To configure MU EDCA timer value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_TIMER = 19, + + /* 8-bit unsigned value to configure the HE trigger frame MAC padding + * duration. + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_he_mac_padding_dur values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR = 20, + + /* 8-bit unsigned value to override the MU EDCA params to defaults + * regardless of the AP beacon MU EDCA params. If it is enabled use + * the default values else use the MU EDCA params from AP beacon. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA = 21, + + /* 8-bit unsigned value to configure the support for receiving + * an MPDU that contains an operating mode control subfield. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP = 22, + + /* Nested attribute values required to setup the TWT session. + * enum qca_wlan_vendor_attr_twt_setup provides the necessary + * information to set up the session. It contains broadcast flags, + * set_up flags, trigger value, flow type, flow ID, wake interval + * exponent, protection, target wake time, wake duration, wake interval + * mantissa. These nested attributes are used to setup a host triggered + * TWT session. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP = 23, + + /* This nested attribute is used to terminate the current TWT session. + * It does not currently carry any attributes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE = 24, + + /* This nested attribute is used to suspend the current TWT session. + * It does not currently carry any attributes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SUSPEND = 25, + + /* Nested attribute values to indicate the request for resume. + * This attribute is used to resume the TWT session. + * enum qca_wlan_vendor_attr_twt_resume provides the necessary + * parameters required to resume the TWT session. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME = 26, + + /* 8-bit unsigned value to set the HE operating mode control + * (OM CTRL) Channel Width subfield. + * The Channel Width subfield indicates the operating channel width + * supported by the STA for both reception and transmission. + * Uses the enum qca_wlan_he_om_ctrl_ch_bw values. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW = 27, + + /* 8-bit unsigned value to configure the number of spatial + * streams in HE operating mode control field. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS = 28, + + /* Flag attribute to configure the UL MU disable bit in + * HE operating mode control field. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_UL_MU_DISABLE = 29, + + /* Flag attribute to clear the previously set HE operating mode + * control field configuration. + * This attribute is used to configure the testbed device to reset + * defaults to clear any previously set HE operating mode control + * field configuration. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG = 30, + + /* 8-bit unsigned value to configure HE single user PPDU + * transmission. By default this setting is disabled and it + * is disabled in the reset defaults of the device configuration. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU = 31, + + /* 8-bit unsigned value to configure action frame transmission + * in HE trigger based PPDU transmission. + * By default this setting is disabled and it is disabled in + * the reset defaults of the device configuration. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU = 32, + + /* Nested attribute to indicate HE operating mode control field + * transmission. It contains operating mode control field Nss, + * channel bandwidth, Tx Nsts and UL MU disable attributes. + * These nested attributes are used to send HE operating mode control + * with configured values. + * Uses the enum qca_wlan_vendor_attr_he_omi_tx attributes. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX = 33, + + /* 8-bit unsigned value to configure +HTC_HE support to indicate the + * support for the reception of a frame that carries an HE variant + * HT Control field. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP = 34, + + /* 8-bit unsigned value to configure VHT support in 2.4G band. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT = 35, + + /* 8-bit unsigned value to configure HE testbed defaults. + * This attribute is used to configure the testbed device. + * 1-set the device HE capabilities to testbed defaults. + * 0-reset the device HE capabilities to supported config. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS = 36, + + /* 8-bit unsigned value to configure TWT request support. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT = 37, + + /* 8-bit unsigned value to configure protection for Management + * frames when PMF is enabled for the association. + * This attribute is used to configure the testbed device. + * 0-use the correct key, 1-use an incorrect key, 2-disable protection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION = 38, + + /* Flag attribute to inject Disassociation frame to the connected AP. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX = 39, + + /* 8-bit unsigned value to configure an override for the RSNXE Used + * subfield in the MIC control field of the FTE in FT Reassociation + * Request frame. + * 0 - Default behavior, 1 - override with 1, 2 - override with 0. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED = 40, + + /* 8-bit unsigned value to configure the driver to ignore CSA (Channel + * Switch Announcement) when STA is in connected state. + * 0 - Default behavior, 1 - Ignore CSA. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA = 41, + + /* Nested attribute values required to configure OCI (Operating Channel + * Information). Attributes defined in enum + * qca_wlan_vendor_attr_oci_override are nested within this attribute. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE = 42, + + /* 8-bit unsigned value to configure the driver/firmware to ignore SA + * Query timeout. If this configuration is enabled STA shall not send + * Deauthentication frmae when SA Query times out (mainly, after a + * channel switch when OCV is enabled). + * 0 - Default behavior, 1 - Ignore SA Query timeout. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT = 43, + + /* 8-bit unsigned value to configure the driver/firmware to start or + * stop transmitting FILS discovery frames. + * 0 - Stop transmitting FILS discovery frames + * 1 - Start transmitting FILS discovery frames + * This attribute is used to configure the testbed device. + * This attribute can be configured only in AP mode and the + * configuration is valid until AP restart. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities + * information field. + * 0 - Disable full bandwidth UL MU-MIMO subfield + * 1 - Enable full bandwidth UL MU-MIMO subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45, + + /* 16-bit unsigned value to configure the driver with a specific BSS + * max idle period to advertise in the BSS Max Idle Period element + * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46, + + /* 8-bit unsigned value to configure the driver to use only RU 242 tone + * for data transmission. + * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47, + + /* 8-bit unsigned value to configure the driver to disable data and + * management response frame transmission to test the BSS max idle + * feature. + * 0 - Default behavior, 1 - Disable data and management response Tx. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Punctured Preamble Rx subfield in the HE PHY capabilities + * information field. + * 0 - Disable Punctured Preamble Rx subfield + * 1 - Enable Punctured Preamble Rx subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49, + + /* 8-bit unsigned value to configure the driver to ignore the SAE H2E + * requirement mismatch for 6 GHz connection. + * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50, + + /* 8-bit unsigned value to configure the driver to allow 6 GHz + * connection with all security modes. + * 0 - Default behavior, 1 - Allow 6 GHz connection with all security + * modes. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51, + + /* 8-bit unsigned value to configure the driver to transmit data with + * ER SU PPDU type. + * + * 0 - Default behavior, 1 - Enable ER SU PPDU type TX. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52, + + /* 8-bit unsigned value to configure the driver to use Data or + * Management frame type for keep alive data. + * Uses enum qca_wlan_keep_alive_data_type values. + * + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53, + + /* 8-bit unsigned value to configure the driver to use scan request + * BSSID value in Probe Request frame RA(A1) during the scan. The + * driver saves this configuration and applies this setting to all user + * space scan requests until the setting is cleared. If this + * configuration is set, the driver uses the BSSID value from the scan + * request to set the RA(A1) in the Probe Request frames during the + * scan. + * + * 0 - Default behavior uses the broadcast RA in Probe Request frames. + * 1 - Uses the scan request BSSID in RA in Probe Request frames. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54, + + /* 8-bit unsigned value to configure the driver to enable/disable the + * BSS max idle period support. + * + * 0 - Disable the BSS max idle support. + * 1 - Enable the BSS max idle support. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Rx control frame to MultiBSS subfield in the HE MAC + * capabilities information field. + * 0 - Disable Rx control frame to MultiBSS subfield + * 1 - Enable Rx control frame to MultiBSS subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Broadcast TWT support subfield in the HE MAC capabilities + * information field. + * 0 - Disable Broadcast TWT support subfield + * 1 - Enable Broadcast TWT support subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_twt_operation - Operation of the config TWT request + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION. + * The response for the respective operations can be either synchronous or + * asynchronous (wherever specified). If synchronous, the response to this + * operation is obtained in the corresponding vendor command reply to the user + * space. For the asynchronous case the response is obtained as an event with + * the same operation type. + * + * Drivers shall support either of these modes but not both simultaneously. + * This support for asynchronous mode is advertised through the flag + * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised, + * the driver shall support synchronous mode. + * + * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured + * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Depending upon the + * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a + * synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation. + * + * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup. + * This terminate can either get triggered by the user space or can as well be + * a notification from the firmware if it initiates a terminate. + * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, + * the request from user space can either be a synchronous or asynchronous + * operation. + * + * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup. + * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, + * this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are + * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup. + * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE + * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT + * capability, this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a + * combination of suspend and resume in a single request. Required parameters + * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the + * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is + * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT + * capability, this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information. + * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT + * session is setup. It's a synchronous operation. + * + * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information. + * Valid only after the TWT session is setup. It's a synchronous operation. + * + * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its + * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous + * operation. + * + * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmware is + * ready for a new TWT session setup after it issued a TWT teardown. + * + * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required + * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer + * the enum qca_wlan_vendor_attr_twt_set_param. + * + * @QCA_WLAN_TWT_NOTIFY: Used to notify userspace about changes in TWT + * related information for example TWT required bit in AP capabilities etc. + * The reason for the notification is sent using + * QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS. + */ +enum qca_wlan_twt_operation { + QCA_WLAN_TWT_SET = 0, + QCA_WLAN_TWT_GET = 1, + QCA_WLAN_TWT_TERMINATE = 2, + QCA_WLAN_TWT_SUSPEND = 3, + QCA_WLAN_TWT_RESUME = 4, + QCA_WLAN_TWT_NUDGE = 5, + QCA_WLAN_TWT_GET_STATS = 6, + QCA_WLAN_TWT_CLEAR_STATS = 7, + QCA_WLAN_TWT_GET_CAPABILITIES = 8, + QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9, + QCA_WLAN_TWT_SET_PARAM = 10, + QCA_WLAN_TWT_NOTIFY = 11, +}; + +/** + * enum qca_wlan_vendor_attr_config_twt: Defines attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION: u8 attribute. Specify the TWT + * operation of this request. Possible values are defined in enum + * qca_wlan_twt_operation. The parameters for the respective operation is + * specified through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the + * parameters configured for TWT. These parameters are represented by + * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume, + * enum qca_wlan_vendor_attr_twt_set_param, or + * enum qca_wlan_vendor_attr_twt_stats based on the operation. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS: Size is u8, mandatory when + * QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to QCA_WLAN_TWT_NOTIFY. + * The values used by this attribute are defined in + * enum qca_wlan_vendor_twt_status. + */ +enum qca_wlan_vendor_attr_config_twt { + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS = 2, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_NOTIFY_STATUS = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_bss_filter - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * The user can add/delete the filter by specifying the BSSID/STA MAC address in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR, filter type in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE, add/delete action in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION in the request. The user can get the + * statistics of an unassociated station by specifying the MAC address in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR, station type in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE, GET action in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION in the request. The user also can get + * the statistics of all unassociated stations by specifying the Broadcast MAC + * address (ff:ff:ff:ff:ff:ff) in QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR with + * above procedure. In the response, driver shall specify statistics + * information nested in QCA_WLAN_VENDOR_ATTR_BSS_FILTER_STA_STATS. + */ +enum qca_wlan_vendor_attr_bss_filter { + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR = 1, + /* Other BSS filter type, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_bss_filter_type. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE = 2, + /* Other BSS filter action, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_bss_filter_action. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION = 3, + /* Array of nested attributes where each entry is the statistics + * information of the specified station that belong to another BSS. + * Attributes for each entry are taken from enum + * qca_wlan_vendor_bss_filter_sta_stats. + * Other BSS station configured in + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER with filter type + * QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA. + * Statistics returned by QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER + * with filter action QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_STA_STATS = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAX = + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_bss_filter_type - Type of + * filter used in other BSS filter operations. Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_TYPE_BSSID: BSSID filter + * @QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA: Station MAC address filter + */ +enum qca_wlan_vendor_bss_filter_type { + QCA_WLAN_VENDOR_BSS_FILTER_TYPE_BSSID, + QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA, +}; + +/** + * enum qca_wlan_vendor_bss_filter_action - Type of + * action in other BSS filter operations. Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_ADD: Add filter + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_DEL: Delete filter + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET: Get the statistics + */ +enum qca_wlan_vendor_bss_filter_action { + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_ADD, + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_DEL, + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET, +}; + +/** + * enum qca_wlan_vendor_bss_filter_sta_stats - Attributes for + * the statistics of a specific unassociated station belonging to another BSS. + * The statistics provides information of the unassociated station + * filtered by other BSS operation - such as MAC, signal value. + * Used by the vendor command QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAC: MAC address of the station. + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI: Last received signal strength + * of the station. Unsigned 8 bit number containing RSSI. + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI_TS: Time stamp of the host + * driver for the last received RSSI. Unsigned 64 bit number containing + * nanoseconds from the boottime. + */ +enum qca_wlan_vendor_bss_filter_sta_stats { + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_INVALID = 0, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAC = 1, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI = 2, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI_TS = 3, + + /* keep last */ + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAX = + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_AFTER_LAST - 1 +}; + +/* enum qca_wlan_nan_subcmd_type - Type of NAN command used by attribute + * QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE as a part of vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. + */ +enum qca_wlan_nan_ext_subcmd_type { + /* Subcmd of type NAN Enable Request */ + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ = 1, + /* Subcmd of type NAN Disable Request */ + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ = 2, +}; + +/** + * enum qca_wlan_vendor_attr_nan_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. + */ +enum qca_wlan_vendor_attr_nan_params { + QCA_WLAN_VENDOR_ATTR_NAN_INVALID = 0, + /* Carries NAN command for firmware component. Every vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT must contain this attribute with a + * payload containing the NAN command. NLA_BINARY attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA = 1, + /* Indicates the type of NAN command sent with + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. enum qca_wlan_nan_ext_subcmd_type + * describes the possible range of values. This attribute is mandatory + * if the command being issued is either + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ or + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE = 2, + /* Frequency (in MHz) of primary NAN discovery social channel in 2.4 GHz + * band. This attribute is mandatory when command type is + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ = 3, + /* Frequency (in MHz) of secondary NAN discovery social channel in 5 GHz + * band. This attribute is optional and should be included when command + * type is QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ and NAN discovery + * has to be started on 5GHz along with 2.4GHz. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_AFTER_LAST - 1 +}; + +/** + * qca_wlan_twt_setup_state: Represents the TWT session states. + * + * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established. + * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active. + * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state. + */ +enum qca_wlan_twt_setup_state { + QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0, + QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1, + QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2, +}; + +/** + * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for + * TWT (Target Wake Time) setup request. These attributes are sent as part of + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST: Flag attribute. + * Disable (flag attribute not present) - Individual TWT + * Enable (flag attribute present) - Broadcast TWT. + * Individual means the session is between the STA and the AP. + * This session is established using a separate negotiation between + * STA and AP. + * Broadcast means the session is across multiple STAs and an AP. The + * configuration parameters are announced in Beacon frames by the AP. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE: Required (u8). + * Unsigned 8-bit qca_wlan_vendor_twt_setup_req_type to + * specify the TWT request type. This is used in TWT SET operation. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER: Flag attribute + * Enable (flag attribute present) - TWT with trigger support. + * Disable (flag attribute not present) - TWT without trigger support. + * Trigger means the AP will send the trigger frame to allow STA to send data. + * Without trigger, the STA will wait for the MU EDCA timer before + * transmitting the data. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE: Required (u8) + * 0 - Announced TWT - In this mode, STA may skip few service periods to + * save more power. If STA wants to wake up, it will send a PS-POLL/QoS + * NULL frame to AP. + * 1 - Unannounced TWT - The STA will wakeup during every SP. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID: Optional (u8) + * Flow ID is the unique identifier for each TWT session. + * If not provided then dialog ID will be set to zero. + * This is an optional parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Request and Response + * 3. TWT TERMINATE Request and Response + * 4. TWT SUSPEND Request and Response + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions for the following + * 1. TWT TERMINATE Request and Response + * 2. TWT SUSPEND Request and Response + * 4. TWT CLEAR STATISTICS request + * 5. TWT GET STATISTICS request and response + * If an invalid dialog ID is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8) + * This attribute (exp) is used along with the mantissa to derive the + * wake interval using the following formula: + * pow(2,exp) = wake_intvl_us/wake_intvl_mantis + * Wake interval is the interval between 2 successive SP. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION: Flag attribute + * Enable (flag attribute present) - Protection required. + * Disable (flag attribute not present) - Protection not required. + * If protection is enabled, then the AP will use protection + * mechanism using RTS/CTS to self to reserve the airtime. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME: Optional (u32) + * This attribute is used as the SP offset which is the offset from + * TSF after which the wake happens. The units are in microseconds. If + * this attribute is not provided, then the value will be set to zero. + * This is an optional parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION: Required (u32) + * This is the duration of the service period. This is specified as + * multiples of 256 microseconds. Valid values are 0x1 to 0xFF. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA: Required (u32) + * This attribute is used to configure wake interval mantissa. + * The units are in TU. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS: Required (u8) + * This field is applicable for TWT response only. + * This contains status values in enum qca_wlan_vendor_twt_status + * and is passed to the userspace. This is used in TWT SET operation. + * This is a required parameter for + * 1. TWT SET Response + * 2. TWT TERMINATE Response + * 3. TWT SUSPEND Response + * 4. TWT RESUME Response + * 5. TWT NUDGE Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8) + * This field is applicable for TWT response only. + * This field contains response type from the TWT responder and is + * passed to the userspace. The values for this field are defined in + * enum qca_wlan_vendor_twt_setup_resp_type. This is used in TWT SET + * response. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64) + * In TWT setup command this field contains absolute TSF that will + * be used by TWT requester during setup. + * In TWT response this field contains absolute TSF value of the + * wake time received from the TWT responder and is passed to + * the userspace. + * This is an optional parameter for + * 1. TWT SET Request + * This is a required parameter for + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED: Flag attribute. + * Enable (flag attribute present) - Indicates that the TWT responder + * supports reception of TWT information frame from the TWT requestor. + * Disable (flag attribute not present) - Indicates that the responder + * doesn't support reception of TWT information frame from requestor. + * This is used in + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which the TWT session + * is being configured. This is used in AP mode to represent the respective + * client. + * In AP mode, this is a required parameter in response for + * 1. TWT SET + * 2. TWT GET + * 3. TWT TERMINATE + * 4. TWT SUSPEND + * In STA mode, this is an optional parameter in request and response for + * the above four TWT operations. + * In AP mode, this is a required parameter in request for + * 1. TWT GET + * 2. TWT TERMINATE + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32) + * Minimum tolerance limit of wake interval parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32) + * Maximum tolerance limit of wake interval parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32) + * Minimum tolerance limit of wake duration parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32) + * Maximum tolerance limit of wake duration parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32) + * TWT state for the given dialog id. The values for this are represented + * by enum qca_wlan_twt_setup_state. + * This is obtained through TWT GET operation. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32) + * This attribute is used to configure wake interval mantissa. + * The unit is microseconds. This attribute, when specified, takes + * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA. + * This parameter is used for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8) + * This attribute is used to configure Broadcast TWT ID. + * The Broadcast TWT ID indicates a specific Broadcast TWT for which the + * transmitting STA is providing TWT parameters. The allowed values are 0 to 31. + * This parameter is used for + * 1. TWT SET Request + * 2. TWT TERMINATE Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8) + * This attribute is used to configure Broadcast TWT recommendation. + * The Broadcast TWT Recommendation subfield contains a value that indicates + * recommendations on the types of frames that are transmitted by TWT + * scheduled STAs and scheduling AP during the broadcast TWT SP. + * The allowed values are 0 - 3. + * This parameter is used for + * 1. TWT SET Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8) + * This attribute is used to configure Broadcast TWT Persistence. + * The Broadcast TWT Persistence subfield indicates the number of + * TBTTs during which the Broadcast TWT SPs corresponding to this + * broadcast TWT Parameter set are present. The number of beacon intervals + * during which the Broadcast TWT SPs are present is equal to the value in the + * Broadcast TWT Persistence subfield plus 1 except that the value 255 + * indicates that the Broadcast TWT SPs are present until explicitly terminated. + * This parameter is used for + * 1. TWT SET Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8) + * This attribute contains the value of the Responder PM Mode subfield (0 or 1) + * from TWT response frame. + * This parameter is used for + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32) + * This attribute is used to configure the announce timeout value (in us) in + * the firmware. This timeout value is only applicable for the announced TWT. If + * the timeout value is non-zero the firmware waits up to the timeout value to + * use Data frame as an announcement frame. If the timeout value is 0 the + * firmware sends an explicit QoS NULL frame as the announcement frame on SP + * start. The default value in the firmware is 0. + * This parameter is used for + * 1. TWT SET Request + */ +enum qca_wlan_vendor_attr_twt_setup { + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST = 1, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER = 3, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE = 4, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID = 5, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP = 6, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION = 7, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME = 8, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA = 10, + + /* TWT Response only attributes */ + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS = 11, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE = 12, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF = 13, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_twt_status - Represents the status of the requested + * TWT operation + * + * @QCA_WLAN_VENDOR_TWT_STATUS_OK: TWT request successfully completed + * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED: TWT not enabled + * @QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID: TWT dialog ID is already used + * @QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY: TWT session is busy + * @QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST: TWT session does not exist + * @QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED: TWT session not in suspend state + * @QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM: Invalid parameters + * @QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY: FW not ready + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE: FW resource exhausted + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK: Peer AP/STA did not ACK the + * request/response frame + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE: Peer AP did not send the response + * frame + * @QCA_WLAN_VENDOR_TWT_STATUS_DENIED: AP did not accept the request + * @QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: Adding TWT dialog failed due to an + * unknown reason + * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in + * suspend state + * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to + * invalid IE in the received TWT frame + * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from + * the responder are not in the specified range + * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT + * session due to request from the responder. Used on the TWT_TERMINATE + * notification from the firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT + * session due to roaming. Used on the TWT_TERMINATE notification from the + * firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the + * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel + * Concurrency). Used on the TWT_TERMINATE notification from the firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup + * request due to roaming in progress. + * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT + * setup request due to channel switch in progress. + * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup + * request due to scan in progress. + * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to + * terminate an existing TWT session on power save exit request from userspace. + * Used on the TWT_TERMINATE notification from the driver/firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_REQUIRED: The peer has set the TWT + * required bit in its capabilities. + * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_REQUIRED: The peer has cleared + * the TWT required bit(1->0) in its capabilities. + */ +enum qca_wlan_vendor_twt_status { + QCA_WLAN_VENDOR_TWT_STATUS_OK = 0, + QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED = 1, + QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID = 2, + QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY = 3, + QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST = 4, + QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED = 5, + QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM = 6, + QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY = 7, + QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE = 8, + QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK = 9, + QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE = 10, + QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11, + QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12, + QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13, + QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14, + QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15, + QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16, + QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17, + QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18, + QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19, + QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20, + QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21, + QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22, + QCA_WLAN_VENDOR_TWT_STATUS_TWT_REQUIRED = 23, + QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_REQUIRED = 24, +}; + +/** + * enum qca_wlan_vendor_attr_twt_resume - Represents attributes for + * TWT (Target Wake Time) resume request. These attributes are sent as part of + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME and + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT: Optional (u8) + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT: Optional (u32) + * These attributes are used as the SP offset which is the offset from TSF after + * which the wake happens. The units are in microseconds. Please note that + * _NEXT_TWT is limited to u8 whereas _NEXT2_TWT takes the u32 data. + * _NEXT2_TWT takes the precedence over _NEXT_TWT and thus the recommendation + * is to use _NEXT2_TWT. If neither of these attributes is provided, the value + * will be set to zero. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE: Required (u32) + * This attribute represents the next TWT subfield size. + * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits, + * and 4 for 64 bits. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8). + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session to resume. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions. + * If an invalid dialog id is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer to which TWT Resume is + * being sent. This is used in AP mode to represent the respective + * client and is a required parameter. In STA mode, this is an optional + * parameter + */ +enum qca_wlan_vendor_attr_twt_resume { + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT = 1, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE = 2, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID = 3, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT = 4, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for + * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend + * and resume in a single request. These attributes are sent as part of + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8) + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session to suspend and resume. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request + * and response. + * If an invalid dialog id is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32) + * This attribute is used as the SP offset which is the offset from + * TSF after which the wake happens. The units are in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32) + * This attribute represents the next TWT subfield size. + * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits, + * and 4 for 64 bits. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer to which TWT Suspend and Resume is + * being sent. This is used in AP mode to represent the respective + * client and is a required parameter. In STA mode, this is an optional + * parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64) + * This field contains absolute TSF value of the time at which the TWT + * session will be resumed. + */ +enum qca_wlan_vendor_attr_twt_nudge { + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for + * TWT (Target Wake Time) get statistics and clear statistics request. + * These attributes are sent as part of + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8) + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session for get and clear TWT statistics. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions in + * 1) TWT GET STATISTICS request and response + * 2) TWT CLEAR STATISTICS request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which TWT Statistics + * is required. + * In AP mode this is used to represent the respective + * client and is a required parameter for + * 1) TWT GET STATISTICS request and response + * 2) TWT CLEAR STATISTICS request and response + * In STA mode, this is an optional parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32) + * This is the duration of the service period in microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32) + * Average of the actual wake duration observed so far. Unit is microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32) + * The number of TWT service periods elapsed so far. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32) + * This is the minimum value of the wake duration observed across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is + * microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32) + * This is the maximum value of wake duration observed across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is + * microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32) + * Average number of MPDUs transmitted successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32) + * Average number of MPDUs received successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32) + * Average number of bytes transmitted successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32) + * Average number of bytes received successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32) + * Status of the TWT GET STATISTICS request. + * This contains status values in enum qca_wlan_vendor_twt_status + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + */ +enum qca_wlan_vendor_attr_twt_stats { + QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1, +}; + +/** + * qca_wlan_twt_get_capa - Represents the bitmap of TWT capabilities + * supported by the device and the peer. + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES + * + * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by + * TWT non-scheduling STA. This capability is advertised in the HE + * Capability/Extended Capabilities information element in the + * Association Request frame by the device. + * + * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by + * the TWT scheduling AP. This capability is advertised in the Extended + * Capabilities/HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support + * for the broadcast TWT functionality. On the responder side, this indicates + * support for the role of broadcast TWT scheduling functionality. This + * capability is advertised in the HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule. + * This capability is advertised in the HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate + * that it mandates the associated HE STAs to support TWT. This capability is + * advertised by AP in the HE Operation Parameters field of the HE Operation + * information element. + */ +enum qca_wlan_twt_capa { + QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0), + QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1), + QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2), + QCA_WLAN_TWT_CAPA_FLEXIBLE = BIT(3), + QCA_WLAN_TWT_CAPA_REQUIRED = BIT(4), +}; + +/** + * enum qca_wlan_vendor_attr_twt_capability - Represents attributes for TWT + * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT + * operation. + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which the TWT capabilities + * are being queried. This is used in AP mode to represent the respective + * client. In STA mode, this is an optional parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16). + * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in + * enum qca_wlan_twt_capa. + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16). + * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in + * enum qca_wlan_twt_capa. + */ +enum qca_wlan_vendor_attr_twt_capability { + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for + * TWT (Target Wake Time) related parameters. It is used when + * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM. + * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8) + * This attribute configures AC parameters to be used for all TWT + * sessions in AP mode. + * Uses the enum qca_wlan_ac_type values. + */ +enum qca_wlan_vendor_attr_twt_set_param { + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by + * the TWT responder + * + * @QCA_WLAN_VENDOR_TWT_RESP_ALTERNATE: TWT responder suggests TWT + * parameters that are different from TWT requesting STA suggested + * or demanded TWT parameters + * @QCA_WLAN_VENDOR_TWT_RESP_DICTATE: TWT responder demands TWT + * parameters that are different from TWT requesting STA TWT suggested + * or demanded parameters + * @QCA_WLAN_VENDOR_TWT_RESP_REJECT: TWT responder rejects TWT + * setup + * @QCA_WLAN_VENDOR_TWT_RESP_ACCEPT: TWT responder accepts the TWT + * setup. + */ +enum qca_wlan_vendor_twt_setup_resp_type { + QCA_WLAN_VENDOR_TWT_RESP_ALTERNATE = 1, + QCA_WLAN_VENDOR_TWT_RESP_DICTATE = 2, + QCA_WLAN_VENDOR_TWT_RESP_REJECT = 3, + QCA_WLAN_VENDOR_TWT_RESP_ACCEPT = 4, +}; + +/** + * enum qca_wlan_vendor_twt_setup_req_type - Required (u8) + * Represents the setup type being requested for TWT. + * @QCA_WLAN_VENDOR_TWT_SETUP_REQUEST: STA is not specifying all the TWT + * parameters but relying on AP to fill the parameters during the negotiation. + * @QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST: STA will provide all the suggested + * values which the AP may accept or AP may provide alternative parameters + * which the STA may accept. + * @QCA_WLAN_VENDOR_TWT_SETUP_DEMAND: STA is not willing to accept any + * alternate parameters than the requested ones. + */ +enum qca_wlan_vendor_twt_setup_req_type { + QCA_WLAN_VENDOR_TWT_SETUP_REQUEST = 1, + QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST = 2, + QCA_WLAN_VENDOR_TWT_SETUP_DEMAND = 3, +}; + +/** + * enum qca_wlan_roam_scan_event_type - Type of roam scan event + * + * Indicates the type of roam scan event sent by firmware/driver. + * + * @QCA_WLAN_ROAM_SCAN_TRIGGER_EVENT: Roam scan trigger event type. + * @QCA_WLAN_ROAM_SCAN_STOP_EVENT: Roam scan stopped event type. + */ +enum qca_wlan_roam_scan_event_type { + QCA_WLAN_ROAM_SCAN_TRIGGER_EVENT = 0, + QCA_WLAN_ROAM_SCAN_STOP_EVENT = 1, +}; + +/** + * enum qca_wlan_roam_scan_trigger_reason - Roam scan trigger reason + * + * Indicates the reason for triggering roam scan by firmware/driver. + * + * @QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_LOW_RSSI: Due to low RSSI of current AP. + * @QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_HIGH_PER: Due to high packet error rate. + */ +enum qca_wlan_roam_scan_trigger_reason { + QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_LOW_RSSI = 0, + QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_HIGH_PER = 1, +}; + +/** + * enum qca_wlan_vendor_attr_roam_scan - Vendor subcmd attributes to report + * roam scan related details from driver/firmware to user space. enum values + * are used for NL attributes sent with + * %QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT sub command. + */ +enum qca_wlan_vendor_attr_roam_scan { + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_INVALID = 0, + /* Encapsulates type of roam scan event being reported. enum + * qca_wlan_roam_scan_event_type describes the possible range of + * values. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_EVENT_TYPE = 1, + /* Encapsulates reason for triggering roam scan. enum + * qca_wlan_roam_scan_trigger_reason describes the possible range of + * values. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_TRIGGER_REASON = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data + * transport modes and is used by the attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor + * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. + * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data. + * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR + * data. The data shall be encapsulated within + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command + * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event. + */ +enum qca_wlan_vendor_cfr_data_transport_modes { + QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0, + QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1, +}; + +/** + * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor + * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. + * @QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL: CFR method using QoS Null frame + * @QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE: CFR method using QoS Null frame + * with phase + * @QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE: CFR method using Probe Response frame + */ +enum qca_wlan_vendor_cfr_method { + QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL = 0, + QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE = 1, + QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE = 2, +}; + +/** + * enum qca_wlan_vendor_cfr_capture_type - QCA vendor CFR capture type used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE. + * @QCA_WLAN_VENDOR_CFR_DIRECT_FTM: Filter directed FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK: Filter all FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP: Filter NDPA NDP directed frames. + * @QCA_WLAN_VENDOR_CFR_TA_RA: Filter frames based on TA/RA/Subtype which + * is provided by one or more of below attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * @QCA_WLAN_CFR_ALL_PACKET: Filter all packets. + * @QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL: Filter all NDPA NDP frames. + */ +enum qca_wlan_vendor_cfr_capture_type { + QCA_WLAN_VENDOR_CFR_DIRECT_FTM = 0, + QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK = 1, + QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP = 2, + QCA_WLAN_VENDOR_CFR_TA_RA = 3, + QCA_WLAN_VENDOR_CFR_ALL_PACKET = 4, + QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL = 5, +}; + +/** + * enum qca_wlan_vendor_peer_cfr_capture_attr - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG to configure peer + * Channel Frequency Response capture parameters and enable periodic CFR + * capture. + * + * @QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR: Optional (6-byte MAC address) + * MAC address of peer. This is for CFR version 1 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE: Required (flag) + * Enable peer CFR capture. This attribute is mandatory to enable peer CFR + * capture. If this attribute is not present, peer CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH: Optional (u8) + * BW of measurement, attribute uses the values in enum nl80211_chan_width + * Supported values: 20, 40, 80, 80+80, 160. + * Note that all targets may not support all bandwidths. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY: Optional (u32) + * Periodicity of CFR measurement in milliseconds. + * Periodicity should be a multiple of Base timer. + * Current Base timer value supported is 10 milliseconds (default). + * 0 for one shot capture. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD: Optional (u8) + * Method used to capture Channel Frequency Response. + * Attribute uses the values defined in enum qca_wlan_vendor_cfr_method. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE: Optional (flag) + * Enable periodic CFR capture. + * This attribute is mandatory for version 1 to enable Periodic CFR capture. + * If this attribute is not present, periodic CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION: Optional (u8) + * Value is 1 or 2 since there are two versions of CFR capture. Two versions + * can't be enabled at same time. This attribute is mandatory if target + * support both versions and use one of them. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP: Optional (u32) + * This attribute is mandatory for version 2 if + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY is used. + * Bits 15:0 bitfield indicates which group is to be enabled. + * Bits 31:16 Reserved for future use. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION: Optional (u32) + * CFR capture duration in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL: Optional (u32) + * CFR capture interval in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE: Optional (u32) + * CFR capture type is defined in enum qca_wlan_vendor_cfr_capture_type. + * This attribute is mandatory for version 2. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK: Optional (u64) + * Bitfield indicating which user in the current UL MU transmissions are + * enabled for CFR capture. Bits 36 to 0 indicate user indexes for 37 users in + * a UL MU transmission. If bit 0 is set, the CFR capture will happen for user + * index 0 in the current UL MU transmission. If bits 0 and 2 are set, CFR + * capture for UL MU TX corresponds to user indices 0 and 2. Bits 63:37 are + * reserved for future use. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT: Optional (u32) + * Indicates the number of consecutive RX frames to be skipped before CFR + * capture is enabled again. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE: Nested attribute containing + * one or more %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY attributes. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY: Nested attribute containing + * the following group attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER: Optional (u32) + * Target supports multiple groups for some configurations. The group number + * can be any value between 0 and 15. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA: Optional (6-byte MAC address) + * Transmitter address which is used to filter frames. This MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA: Optional (6-byte MAC address) + * Receiver address which is used to filter frames. This MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK: Optional (6-byte MAC address) + * Mask of transmitter address which is used to filter frames. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK: Optional (6-byte MAC address) + * Mask of receiver address which is used to filter frames. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS: Optional (u32) + * Indicates frames with a specific NSS will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 7:0 request CFR + * capture to be done for frames matching the NSS specified within this bitmask. + * Bits 31:8 are reserved for future use. Bits 7:0 map to NSS: + * bit 0 : NSS 1 + * bit 1 : NSS 2 + * ... + * bit 7 : NSS 8 + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW: Optional (u32) + * Indicates frames with a specific bandwidth will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 4:0 request CFR + * capture to be done for frames matching the bandwidths specified within this + * bitmask. Bits 31:5 are reserved for future use. Bits 4:0 map to bandwidth + * numerated in enum nl80211_band (although not all bands may be supported + * by a given device). + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER: Optional (u32) + * Management frames matching the subtype filter categories will be filtered in + * by MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Management frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. For example, Beacon frame control type + * is 8 and its value is 1 << 8 = 0x100. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER: Optional (u32) + * Control frames matching the subtype filter categories will be filtered in by + * MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Control frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER: Optional (u32) + * Data frames matching the subtype filter categories will be filtered in by + * MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Data frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8) + * Userspace can use this attribute to specify the driver about which transport + * mode shall be used by the driver to send CFR data to userspace. Uses values + * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is + * not present, the driver shall use the default transport mechanism which is + * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32) + * Userspace can use this attribute to specify the nl port id of the application + * which receives the CFR data and processes it further so that the drivers can + * unicast the netlink events to a specific application. Optionally included + * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to + * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers + * shall multicast the netlink events when this attribute is not included. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY). + * This attribute will be used by the driver to encapsulate and send CFR data + * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an + * asynchronous event when the driver is configured to send CFR data using + * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS. + */ +enum qca_wlan_vendor_peer_cfr_capture_attr { + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE = 2, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH = 3, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY = 4, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD = 5, + QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE = 6, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION = 7, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP = 8, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL = 10, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE = 11, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK = 12, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE = 14, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY = 15, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER = 16, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA = 17, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA = 18, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK = 19, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK = 20, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS = 21, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW = 22, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX = + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_throughput_level - Current throughput level + * + * Indicates the current level of throughput calculated by the driver. The + * driver may choose different thresholds to decide whether the throughput level + * is low or medium or high based on variety of parameters like physical link + * capacity of the current connection, the number of packets being dispatched + * per second, etc. The throughput level events might not be consistent with the + * actual current throughput value being observed. + * + * @QCA_WLAN_THROUGHPUT_LEVEL_LOW: Low level of throughput + * @QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM: Medium level of throughput + * @QCA_WLAN_THROUGHPUT_LEVEL_HIGH: High level of throughput + */ +enum qca_wlan_throughput_level { + QCA_WLAN_THROUGHPUT_LEVEL_LOW = 0, + QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM = 1, + QCA_WLAN_THROUGHPUT_LEVEL_HIGH = 2, +}; + +/** + * enum qca_wlan_vendor_attr_throughput_change - Vendor subcmd attributes to + * report throughput changes from the driver to user space. enum values are used + * for netlink attributes sent with + * %QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT sub command. + */ +enum qca_wlan_vendor_attr_throughput_change { + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_INVALID = 0, + /* Indicates the direction of throughput in which the change is being + * reported. u8 attribute. Value is 0 for TX and 1 for RX. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION = 1, + /* Indicates the newly observed throughput level. enum + * qca_wlan_throughput_level describes the possible range of values. + * u8 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL = 2, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_limit_output_bytes. u32 attribute. The + * driver may optionally include this attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES = 3, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_adv_win_scale. s8 attribute. Possible + * values are from -31 to 31. The driver may optionally include this + * attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE = 4, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_delack_seg. u32 attribute. The driver may + * optionally include this attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX = + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST - 1, +}; + +/** + * enum qca_coex_config_profiles - This enum defines different types of + * traffic streams that can be prioritized one over the other during coex + * scenarios. + * The types defined in this enum are categorized in the below manner. + * 0 - 31 values corresponds to WLAN + * 32 - 63 values corresponds to BT + * 64 - 95 values corresponds to Zigbee + * @QCA_WIFI_STA_DISCOVERY: Prioritize discovery frames for WLAN STA + * @QCA_WIFI_STA_CONNECTION: Prioritize connection frames for WLAN STA + * @QCA_WIFI_STA_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN STA + * @QCA_WIFI_STA_DATA : Prioritize data frames for WLAN STA + * @QCA_WIFI_STA_ALL: Priritize all frames for WLAN STA + * @QCA_WIFI_SAP_DISCOVERY: Prioritize discovery frames for WLAN SAP + * @QCA_WIFI_SAP_CONNECTION: Prioritize connection frames for WLAN SAP + * @QCA_WIFI_SAP_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN SAP + * @QCA_WIFI_SAP_DATA: Prioritize data frames for WLAN SAP + * @QCA_WIFI_SAP_ALL: Prioritize all frames for WLAN SAP + * @QCA_BT_A2DP: Prioritize BT A2DP + * @QCA_BT_BLE: Prioritize BT BLE + * @QCA_BT_SCO: Prioritize BT SCO + * @QCA_ZB_LOW: Prioritize Zigbee Low + * @QCA_ZB_HIGH: Prioritize Zigbee High + */ +enum qca_coex_config_profiles { + /* 0 - 31 corresponds to WLAN */ + QCA_WIFI_STA_DISCOVERY = 0, + QCA_WIFI_STA_CONNECTION = 1, + QCA_WIFI_STA_CLASS_3_MGMT = 2, + QCA_WIFI_STA_DATA = 3, + QCA_WIFI_STA_ALL = 4, + QCA_WIFI_SAP_DISCOVERY = 5, + QCA_WIFI_SAP_CONNECTION = 6, + QCA_WIFI_SAP_CLASS_3_MGMT = 7, + QCA_WIFI_SAP_DATA = 8, + QCA_WIFI_SAP_ALL = 9, + QCA_WIFI_CASE_MAX = 31, + /* 32 - 63 corresponds to BT */ + QCA_BT_A2DP = 32, + QCA_BT_BLE = 33, + QCA_BT_SCO = 34, + QCA_BT_CASE_MAX = 63, + /* 64 - 95 corresponds to Zigbee */ + QCA_ZB_LOW = 64, + QCA_ZB_HIGH = 65, + QCA_ZB_CASE_MAX = 95, + /* 0xff is default value if the u8 profile value is not set. */ + QCA_COEX_CONFIG_PROFILE_DEFAULT_VALUE = 255 +}; + +/** + * enum qca_vendor_attr_coex_config_types - Coex configurations types. + * This enum defines the valid set of values of coex configuration types. These + * values may used by attribute + * %QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE. + * + * @QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_RESET: Reset all the + * weights to default values. + * @QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_START: Start to config + * weights with configurability value. + */ +enum qca_vendor_attr_coex_config_types { + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_RESET = 1, + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_START = 2, +}; + +/** + * enum qca_vendor_attr_coex_config - Specifies vendor coex config attributes + * + * @QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES: This attribute contains variable + * length array of 8-bit values from enum qca_coex_config_profiles. + * FW will prioritize the profiles in the order given in the array encapsulated + * in this attribute. + * For example: + * ----------------------------------------------------------------------- + * | 1 | 34 | 32 | 65 | + * ----------------------------------------------------------------------- + * If the attribute contains the values defined in above array then it means + * 1) Wifi STA connection has priority over BT_SCO, BT_A2DP and ZIGBEE HIGH. + * 2) BT_SCO has priority over BT_A2DP. + * 3) BT_A2DP has priority over ZIGBEE HIGH. + * Profiles which are not listed in this array shall not be preferred over the + * profiles which are listed in the array as a part of this attribute. + */ +enum qca_vendor_attr_coex_config { + QCA_VENDOR_ATTR_COEX_CONFIG_INVALID = 0, + QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES = 1, + + /* Keep last */ + QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST, + QCA_VENDOR_ATTR_COEX_CONFIG_MAX = + QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_coex_config_three_way - Specifies vendor coex config + * attributes + * Attributes for data used by QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG + * + * QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE: u32 attribute. + * Indicate config type. + * The config types are 32-bit values from qca_vendor_attr_coex_config_types + * + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1: u32 attribute. + * Indicate the Priority 1 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2: u32 attribute. + * Indicate the Priority 2 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3: u32 attribute. + * Indicate the Priority 3 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4: u32 attribute. + * Indicate the Priority 4 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * NOTE: + * Limitations for QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_x priority + * arrangement: + * 1: In the same u32 attribute (priority x), the profiles enum values own + * same priority level. + * 2: 0xff is default value if the u8 profile value is not set. + * 3: max to 4 rules/profiles in same priority level. + * 4: max to 4 priority level (priority 1 - priority 4) + * 5: one priority level only supports one scenario from WLAN/BT/ZB, + * hybrid rules not support. + * 6: if WMI_COEX_CONFIG_THREE_WAY_COEX_RESET called, priority x will + * remain blank to reset all parameters. + * For example: + * + * If the attributes as follow: + * priority 1: + * ------------------------------------ + * | 0xff | 0 | 1 | 2 | + * ------------------------------------ + * priority 2: + * ------------------------------------- + * | 0xff | 0xff | 0xff | 32 | + * ------------------------------------- + * priority 3: + * ------------------------------------- + * | 0xff | 0xff | 0xff | 65 | + * ------------------------------------- + * then it means: + * 1: WIFI_STA_DISCOVERY, WIFI_STA_CLASS_3_MGMT and WIFI_STA_CONNECTION + * owns same priority level. + * 2: WIFI_STA_DISCOVERY, WIFI_STA_CLASS_3_MGMT and WIFI_STA_CONNECTION + * has priority over BT_A2DP and ZB_HIGH. + * 3: BT_A2DP has priority over ZB_HIGH. + */ +enum qca_vendor_attr_coex_config_three_way { + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_INVALID = 0, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE = 1, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1 = 2, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2 = 3, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3 = 4, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4 = 5, + + /* Keep last */ + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_AFTER_LAST, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX = + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_link_properties - Represent the link properties. + * + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR: MAC address of the peer + * (STA/AP) for the connected link. + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS: Attribute containing a + * &struct nl80211_sta_flag_update for the respective connected link. MAC + * address of the peer represented by + * QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR. + */ +enum qca_wlan_vendor_attr_link_properties { + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0, + /* 1 - 3 are reserved */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR = 4, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS = 5, + + /* Keep last */ + QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST, + QCA_VENDOR_ATTR_LINK_PROPERTIES_MAX = + QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_peer_stats_cache_type - Represents peer stats cache type + * This enum defines the valid set of values of peer stats cache types. These + * values are used by attribute + * %QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_TX_RATE_STATS: Represents peer TX rate statistics + * @QCA_WLAN_VENDOR_ATTR_PEER_RX_RATE_STATS: Represents peer RX rate statistics + * @QCA_WLAN_VENDOR_ATTR_PEER_TX_SOJOURN_STATS: Represents peer TX sojourn + * statistics + */ +enum qca_vendor_attr_peer_stats_cache_type { + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_PEER_TX_RATE_STATS, + QCA_WLAN_VENDOR_ATTR_PEER_RX_RATE_STATS, + QCA_WLAN_VENDOR_ATTR_PEER_TX_SOJOURN_STATS, +}; + +/** + * enum qca_wlan_vendor_attr_peer_stats_cache_params - This enum defines + * attributes required for QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH + * Information in these attributes is used to flush peer rate statistics from + * the driver to user application. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE: Unsigned 32-bit attribute + * Indicate peer statistics cache type. + * The statistics types are 32-bit values from + * enum qca_vendor_attr_peer_stats_cache_type. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC: Unsigned 8-bit array + * of size 6 octets, representing the peer MAC address. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA: Opaque data attribute + * containing buffer of statistics to send to application layer entity. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE: Unsigned 64-bit attribute + * representing a cookie for peer unique session. + */ +enum qca_wlan_vendor_attr_peer_stats_cache_params { + QCA_WLAN_VENDOR_ATTR_PEER_STATS_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC = 2, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA = 3, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE = 4, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_LAST, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX = + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_LAST - 1 +}; + +/** + * enum qca_mpta_helper_attr_zigbee_state - Current Zigbee state + * This enum defines all the possible states of Zigbee, which can be + * delivered in the QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_STATE attribute. + * + * @ZIGBEE_IDLE: Zigbee in idle state + * @ZIGBEE_FORM_NETWORK: Zigbee forming network + * @ZIGBEE_WAIT_JOIN: Zigbee waiting for joining network + * @ZIGBEE_JOIN: Zigbee joining network + * @ZIGBEE_NETWORK_UP: Zigbee network is up + * @ZIGBEE_HMI: Zigbee in HMI mode + */ +enum qca_mpta_helper_attr_zigbee_state { + ZIGBEE_IDLE = 0, + ZIGBEE_FORM_NETWORK = 1, + ZIGBEE_WAIT_JOIN = 2, + ZIGBEE_JOIN = 3, + ZIGBEE_NETWORK_UP = 4, + ZIGBEE_HMI = 5, +}; + +/* + * enum qca_mpta_helper_vendor_attr - Attributes used in vendor sub-command + * QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG. + */ +enum qca_mpta_helper_vendor_attr { + QCA_MPTA_HELPER_VENDOR_ATTR_INVALID = 0, + /* Optional attribute used to update Zigbee state. + * enum qca_mpta_helper_attr_zigbee_state. + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_STATE = 1, + /* Optional attribute used to configure WLAN duration for Shape-OCS + * during interrupt. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_NON_WLAN_DURATION. + * Value range 0 ~ 300 (ms). + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_WLAN_DURATION = 2, + /* Optional attribute used to configure non-WLAN duration for Shape-OCS + * during interrupt. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_WLAN_DURATION. + * Value range 0 ~ 300 (ms). + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_NON_WLAN_DURATION = 3, + /* Optional attribute used to configure WLAN duration for Shape-OCS + * monitor period. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_NON_WLAN_DURATION. + * Value range 0 ~ 300 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_WLAN_DURATION = 4, + /* Optional attribute used to configure non-WLAN duration for Shape-OCS + * monitor period. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_WLAN_DURATION. + * Value range 0 ~ 300 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_NON_WLAN_DURATION = 5, + /* Optional attribute used to configure OCS interrupt duration. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_OCS_DURATION. + * Value range 1000 ~ 20000 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_OCS_DURATION = 6, + /* Optional attribute used to configure OCS monitor duration. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_OCS_DURATION. + * Value range 1000 ~ 20000 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_OCS_DURATION = 7, + /* Optional attribute used to notify WLAN firmware the current Zigbee + * channel. + * Value range 11 ~ 26 + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_CHAN = 8, + /* Optional attribute used to configure WLAN mute duration. + * Value range 0 ~ 400 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_WLAN_MUTE_DURATION = 9, + + /* keep last */ + QCA_MPTA_HELPER_VENDOR_ATTR_AFTER_LAST, + QCA_MPTA_HELPER_VENDOR_ATTR_MAX = + QCA_MPTA_HELPER_VENDOR_ATTR_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_beacon_reporting_op_types - Defines different types of + * operations for which %QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING can be used. + * Will be used by %QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE. + * + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START: Sent by userspace to the driver + * to request the driver to start reporting Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_STOP: Sent by userspace to the driver to + * request the driver to stop reporting Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO: Sent by the driver to + * userspace to report received Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE: Sent by the driver to userspace + * to indicate that the driver is going to pause reporting Beacon frames. + */ +enum qca_wlan_vendor_beacon_reporting_op_types { + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START = 0, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_STOP = 1, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO = 2, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE = 3, +}; + +/** + * enum qca_wlan_vendor_beacon_reporting_pause_reasons - Defines different types + * of reasons for which the driver is pausing reporting Beacon frames. Will be + * used by %QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON. + * + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_UNSPECIFIED: For unspecified + * reasons. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_SCAN_STARTED: When the + * driver/firmware is starting a scan. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED: When the + * driver/firmware disconnects from the ESS and indicates the disconnection to + * userspace (non-seamless roaming case). This reason code will be used by the + * driver/firmware to indicate stopping of beacon report events. Userspace will + * need to start beacon reporting again (if desired) by sending vendor command + * QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING with + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START after the next connection is + * completed. + */ +enum qca_wlan_vendor_beacon_reporting_pause_reasons { + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_UNSPECIFIED = 0, + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_SCAN_STARTED = 1, + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED = 2, +}; + +/* + * enum qca_wlan_vendor_attr_beacon_reporting_params - List of attributes used + * in vendor sub-command QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING. + */ +enum qca_wlan_vendor_attr_beacon_reporting_params { + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_INVALID = 0, + /* Specifies the type of operation that the vendor command/event is + * intended for. Possible values for this attribute are defined in + * enum qca_wlan_vendor_beacon_reporting_op_types. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE = 1, + /* Optionally set by userspace to request the driver to report Beacon + * frames using asynchronous vendor events when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. NLA_FLAG attribute. + * If this flag is not set, the driver will only update Beacon frames in + * cfg80211 scan cache but not send any vendor events. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_ACTIVE_REPORTING = 2, + /* Optionally used by userspace to request the driver/firmware to report + * Beacon frames periodically when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. + * u32 attribute, indicates the period of Beacon frames to be reported + * and in the units of beacon interval. + * If this attribute is missing in the command, then the default value + * of 1 will be assumed by driver, i.e., to report every Beacon frame. + * Zero is an invalid value. + * If a valid value is received for this attribute, the driver will + * update the cfg80211 scan cache periodically as per the value received + * in this attribute in addition to updating the cfg80211 scan cache + * when there is significant change in Beacon frame IEs. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PERIOD = 3, + /* Used by the driver to encapsulate the SSID when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u8 array with a maximum size of 32. + * + * When generating beacon report from non-MBSSID Beacon frame, the SSID + * will be taken from the SSID element of the received Beacon frame. + * + * When generating beacon report from Multiple BSSID Beacon frame and if + * the BSSID of the current connected BSS matches the BSSID of the + * transmitting BSS, the SSID will be taken from the SSID element of the + * received Beacon frame. + * + * When generating beacon report from Multiple BSSID Beacon frame and if + * the BSSID of the current connected BSS matches the BSSID of one of + * the* nontransmitting BSSs, the SSID will be taken from the SSID field + * included in the nontransmitted BSS profile whose derived BSSID is + * same as the BSSID of the current connected BSS. When there is no + * nontransmitted BSS profile whose derived BSSID is same as the BSSID + * of current connected* BSS, this attribute will not be present. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_SSID = 4, + /* Used by the driver to encapsulate the BSSID of the AP to which STA is + * currently connected to when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u8 array with a + * fixed size of 6 bytes. + * + * When generating beacon report from a Multiple BSSID beacon and the + * current connected BSSID matches one of the nontransmitted BSSIDs in a + * Multiple BSSID set, this BSSID will be that particular nontransmitted + * BSSID and not the transmitted BSSID (i.e., the transmitting address + * of the Beacon frame). + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BSSID = 5, + /* Used by the driver to encapsulate the frequency in MHz on which + * the Beacon frame was received when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is + * set to QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_FREQ = 6, + /* Used by the driver to encapsulate the Beacon interval + * when the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u16 attribute. The value will be copied from the Beacon frame and the + * units are TUs. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BI = 7, + /* Used by the driver to encapsulate the Timestamp field from the Beacon + * frame when the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set + * to QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_TSF = 8, + /* Used by the driver to encapsulate the CLOCK_BOOTTIME when this + * Beacon frame is received in the driver when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u64 attribute, in + * the units of nanoseconds. This value is expected to have accuracy of + * about 10 ms. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BOOTTIME_WHEN_RECEIVED = 9, + /* Used by the driver to encapsulate the IEs of the Beacon frame from + * which this event is generated when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u8 array. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_IES = 10, + /* Used by the driver to specify the reason for the driver/firmware to + * pause sending beacons to userspace when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE. Possible values are + * defined in enum qca_wlan_vendor_beacon_reporting_pause_reasons, u32 + * attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON = 11, + /* Used by the driver to specify whether the driver will automatically + * resume reporting beacon events to userspace later (for example after + * the ongoing off-channel activity is completed etc.) when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE. NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES = 12, + /* Optionally set by userspace to request the driver not to resume + * beacon reporting after a pause is completed, when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. NLA_FLAG attribute. + * If this flag is set, the driver will not resume beacon reporting + * after any pause in beacon reporting is completed. Userspace has to + * send QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START command again in order + * to initiate beacon reporting again. If this flag is set in the recent + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START command, then in the + * subsequent QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE event (if any) + * the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES shall not be + * set by the driver. Setting this flag until and unless there is a + * specific need is not recommended as there is a chance of some beacons + * received after pause command and next start command being not + * reported. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_DO_NOT_RESUME = 13, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_LAST, + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_MAX = + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_LAST - 1 +}; + +/** + * enum qca_vendor_interop_issues_ap_type - Interop issue types + * This enum defines the valid set of values of interop issue types. These + * values are used by attribute %QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE. + * + * @QCA_VENDOR_INTEROP_ISSUES_AP_ON_STA_PS: The AP has power save interop issue + * when the STA's Qpower feature is enabled. + */ +enum qca_vendor_interop_issues_ap_type { + QCA_VENDOR_INTEROP_ISSUES_AP_INVALID = 0, + QCA_VENDOR_INTEROP_ISSUES_AP_ON_STA_PS = 1, +}; + +/** + * enum qca_vendor_attr_interop_issues_ap - attribute for AP with interop issues + * Values are used by %QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP. + * + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_INVALID: Invalid value + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE: Interop issue type + * 32-bit unsigned value. The values defined in enum + * qca_vendor_interop_issues_ap_type are used. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST: APs' BSSID container + * array of nested QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID attributes. + * It is present and mandatory for the command but is not used for the event + * since only a single BSSID is reported in an event. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID: AP's BSSID 6-byte MAC address. + * It is used within the nested QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST + * attribute in command case and without such encapsulation in the event case. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST: last value + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX: max value + */ +enum qca_vendor_attr_interop_issues_ap { + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_INVALID, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX = + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_oem_device_type - Represents the target device in firmware. + * It is used by QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO. + * + * @QCA_VENDOR_OEM_DEVICE_VIRTUAL: The command is intended for + * a virtual device. + * + * @QCA_VENDOR_OEM_DEVICE_PHYSICAL: The command is intended for + * a physical device. + */ +enum qca_vendor_oem_device_type { + QCA_VENDOR_OEM_DEVICE_VIRTUAL = 0, + QCA_VENDOR_OEM_DEVICE_PHYSICAL = 1, +}; + +/** + * enum qca_wlan_vendor_attr_oem_data_params - Used by the vendor command/event + * QCA_NL80211_VENDOR_SUBCMD_OEM_DATA. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA: This NLA_BINARY attribute is + * used to set/query the data to/from the firmware. On query, the same + * attribute is used to carry the respective data in the reply sent by the + * driver to userspace. The request to set/query the data and the format of the + * respective data from the firmware are embedded in the attribute. The + * maximum size of the attribute payload is 1024 bytes. + * Userspace has to set the QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED + * attribute when the data is queried from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO: The binary blob will be routed + * based on this field. This optional attribute is included to specify whether + * the device type is a virtual device or a physical device for the + * command/event. This attribute can be omitted for a virtual device (default) + * command/event. + * This u8 attribute is used to carry information for the device type using + * values defined by enum qca_vendor_oem_device_type. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED: This NLA_FLAG attribute + * is set when the userspace queries data from the firmware. This attribute + * should not be set when userspace sets the OEM data to the firmware. + */ +enum qca_wlan_vendor_attr_oem_data_params { + QCA_WLAN_VENDOR_ATTR_OEM_DATA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA = 1, + QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO = 2, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_avoid_frequency_ext - Defines attributes to be + * used with vendor command/event QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required + * Nested attribute containing multiple ranges with following attributes: + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32) + * Starting center frequency in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32) + * Ending center frequency in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM: + * s32 attribute, optional. It is a per frequency range attribute. + * The maximum TX power limit from user space is to be applied on an + * unrestricted interface for corresponding frequency range. It is also + * possible that the actual TX power may be even lower than this cap due to + * other considerations such as regulatory compliance, SAR, etc. In absence of + * this attribute the driver shall follow current behavior which means + * interface (SAP/P2P) function can keep operating on an unsafe channel with TX + * power derived by the driver based on regulatory/SAR during interface up. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK: + * u32 attribute, optional. Indicates all the interface types which are + * restricted for all frequency ranges provided in + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END. + * This attribute encapsulates bitmasks of interface types defined in + * enum nl80211_iftype. If an interface is marked as restricted the driver must + * move to a safe channel and if no safe channel is available the driver shall + * terminate that interface functionality. In absence of this attribute, + * interface (SAP/P2P) can still continue operating on an unsafe channel with + * TX power limit derived from either + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on + * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM + * is not provided. + */ +enum qca_wlan_vendor_attr_avoid_frequency_ext { + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5, + + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX = + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST - 1 +}; + +/* + * enum qca_wlan_vendor_attr_add_sta_node_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE. + */ +enum qca_wlan_vendor_attr_add_sta_node_params { + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_INVALID = 0, + /* 6 byte MAC address of STA */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_MAC_ADDR = 1, + /* Authentication algorithm used by the station of size u16; + * defined in enum nl80211_auth_type. + */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_AUTH_ALGO = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST - 1 +}; + +/** + * enum qca_btc_chain_mode - Specifies BT coex chain mode. + * This enum defines the valid set of values of BT coex chain mode. + * These values are used by attribute %QCA_VENDOR_ATTR_BTC_CHAIN_MODE of + * %QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_BTC_CHAIN_SHARED: chains of BT and WLAN 2.4G are shared. + * @QCA_BTC_CHAIN_SEPARATED: chains of BT and WLAN 2.4G are separated. + */ +enum qca_btc_chain_mode { + QCA_BTC_CHAIN_SHARED = 0, + QCA_BTC_CHAIN_SEPARATED = 1, +}; + +/** + * enum qca_vendor_attr_btc_chain_mode - Specifies attributes for BT coex + * chain mode. + * Attributes for data used by QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE: u32 attribute. + * Indicates the BT coex chain mode, are 32-bit values from + * enum qca_btc_chain_mode. This attribute is mandatory. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE_RESTART: flag attribute. + * If set, vdev should be restarted when BT coex chain mode is updated. + * This attribute is optional. + */ +enum qca_vendor_attr_btc_chain_mode { + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_INVALID = 0, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE = 1, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART = 2, + + /* Keep last */ + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX = + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST - 1, +}; + +/** + * enum qca_vendor_wlan_sta_flags - Station feature flags + * Bits will be set to 1 if the corresponding features are enabled. + * @QCA_VENDOR_WLAN_STA_FLAG_AMPDU: AMPDU is enabled for the station + * @QCA_VENDOR_WLAN_STA_FLAG_TX_STBC: TX Space-time block coding is enabled + for the station + * @QCA_VENDOR_WLAN_STA_FLAG_RX_STBC: RX Space-time block coding is enabled + for the station + */ +enum qca_vendor_wlan_sta_flags { + QCA_VENDOR_WLAN_STA_FLAG_AMPDU = BIT(0), + QCA_VENDOR_WLAN_STA_FLAG_TX_STBC = BIT(1), + QCA_VENDOR_WLAN_STA_FLAG_RX_STBC = BIT(2), +}; + +/** + * enum qca_vendor_wlan_sta_guard_interval - Station guard interval + * @QCA_VENDOR_WLAN_STA_GI_800_NS: Legacy normal guard interval + * @QCA_VENDOR_WLAN_STA_GI_400_NS: Legacy short guard interval + * @QCA_VENDOR_WLAN_STA_GI_1600_NS: Guard interval used by HE + * @QCA_VENDOR_WLAN_STA_GI_3200_NS: Guard interval used by HE + */ +enum qca_vendor_wlan_sta_guard_interval { + QCA_VENDOR_WLAN_STA_GI_800_NS = 0, + QCA_VENDOR_WLAN_STA_GI_400_NS = 1, + QCA_VENDOR_WLAN_STA_GI_1600_NS = 2, + QCA_VENDOR_WLAN_STA_GI_3200_NS = 3, +}; + +/** + * enum qca_wlan_vendor_attr_get_sta_info - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC: + * Required attribute in request for AP mode only, 6-byte MAC address, + * corresponding to the station's MAC address for which information is + * requested. For STA mode this is not required as the info always correspond + * to the self STA and the current/last association. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS: + * Optionally used in response, u32 attribute, contains a bitmap of different + * fields defined in enum qca_vendor_wlan_sta_flags, used in AP mode only. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL: + * Optionally used in response, u32 attribute, possible values are defined in + * enum qca_vendor_wlan_sta_guard_interval, used in AP mode only. + * Guard interval used by the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames received from station with retry + * bit set to 1 in FC. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter for number of data frames with broadcast or multicast address in + * the destination address received from the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED: + * Optionally used in response, u32 attribute, used in both STA and AP modes. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets and for which the TX status has been updated + * back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA and AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet and for which the TX status has been + * updated back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter in the target for the number of data frames successfully transmitted + * to the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA & AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT: u32, used in + * the STA mode only. Represent the number of probe requests sent by the STA + * while attempting to roam on missing certain number of beacons from the + * connected AP. If queried in the disconnected state, this represents the + * count for the last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT: u32, used in + * the STA mode. Represent the number of probe responses received by the station + * while attempting to roam on missing certain number of beacons from the + * connected AP. When queried in the disconnected state, this represents the + * count when in last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT: u32, used in the + * STA mode only. Represents the total number of frames sent out by STA + * including Data, ACK, RTS, CTS, Control Management. This data is maintained + * only for the connect session. Represents the count of last connected session, + * when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT: u32, used in the STA mode. + * Total number of RTS sent out by the STA. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT: u32, used in the + * STA mode.Represent the number of RTS transmission failure that reach retry + * limit. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT: u32, used in + * the STA mode. Represent the total number of non aggregated frames transmitted + * by the STA. This data is maintained per connect session. Represents the count + * of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT: u32, used in the + * STA mode. Represent the total number of aggregated frames transmitted by the + * STA. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT: u32, used in + * the STA mode. Represents the number of received frames with a good PLCP. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT: u32, + * used in the STA mode. Represents the number of occasions that no valid + * delimiter is detected by A-MPDU parser. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT: u32, used in the + * STA mode. Represents the number of frames for which CRC check failed in the + * MAC. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT: u32, used in the + * STA mode. Represents the number of unicast ACKs received with good FCS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT: u32, used in the STA + * mode. Represents the number of received Block Acks. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT: u32, used in the STA + * mode. Represents the number of beacons received from the connected BSS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT: u32, used in the + * STA mode. Represents the number of beacons received by the other BSS when in + * connected state (through the probes done by the STA). This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT: u64, used in + * the STA mode. Represents the number of received DATA frames with good FCS and + * matching Receiver Address when in connected state. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT: u32, used in the + * STA mode. Represents the number of RX Data multicast frames dropped by the HW + * when in the connected state. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS: u32, used in the + * STA mode. This represents the target power in dBm for the transmissions done + * to the AP in 2.4 GHz at 1 Mbps (DSSS) rate. This data is maintained per + * connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 5 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in + * the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for for transmissions done + * to the AP in 5 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT: u32, used + * in the STA mode. This represents the Nested attribute representing the + * overflow counts of each receive buffer allocated to the hardware during the + * STA's connection. The number of hw buffers might vary for each WLAN + * solution and hence this attribute represents the nested array of all such + * HW buffer count. This data is maintained per connect session. Represents + * the count of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER: u32, Max TX power (dBm) + * allowed as per the regulatory requirements for the current or last connected + * session. Used in the STA mode. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER: u32, Latest TX power + * (dBm) used by the station in its latest unicast frame while communicating + * to the AP in the connected state. When queried in the disconnected state, + * this represents the TX power used by the STA with last AP communication + * when in connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL: u32, Adaptive noise immunity + * level used to adjust the RX sensitivity. Represents the current ANI level + * when queried in the connected state. When queried in the disconnected + * state, this corresponds to the latest ANI level at the instance of + * disconnection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_IES: Binary attribute containing + * the raw information elements from Beacon frames. Represents the Beacon frames + * of the current BSS in the connected state. When queried in the disconnected + * state, these IEs correspond to the last connected BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PROBE_RESP_IES: Binary attribute + * containing the raw information elements from Probe Response frames. + * Represents the Probe Response frames of the current BSS in the connected + * state. When queried in the disconnected state, these IEs correspond to the + * last connected BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_DRIVER_DISCONNECT_REASON: u32, Driver + * disconnect reason for the last disconnection if the disconnection is + * triggered from the host driver. The values are referred from + * enum qca_disconnect_reason_codes. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with an invalid MIC or a missing MME when PMF is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with the packet number less than or equal to the + * last received packet number when PMF is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT: u32, used in STA + * mode only. This represents the number of Beacon frames received from this + * station with an invalid MIC or a missing MME when beacon protection is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode + * only. This represents number of Beacon frames received from this station with + * the packet number less than or equal to the last received packet number when + * beacon protection is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in + * STA mode only. The driver uses this attribute to populate the connection + * failure reason codes and the values are defined in + * enum qca_sta_connect_fail_reason_codes. Userspace applications can send + * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving + * a connection failure indication from the driver. The driver shall not + * include this attribute in response to the + * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection + * failure observed in the last attempted connection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps) + * used by the station in its last TX frame while communicating to the AP in the + * connected state. When queried in the disconnected state, this represents the + * rate used by the STA in the last TX frame to the AP when it was connected. + * This attribute is used for STA mode only. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only. + * This represents the rate index used by the STA for the last TX frame to the + * AP. When queried in the disconnected state, this gives the last RIX used by + * the STA in the last TX frame to the AP when it was connected. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA + * mode only. This represents the number of times the STA TSF goes out of sync + * from the AP after the connection. If queried in the disconnected state, this + * gives the count of TSF out of sync for the last connection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA + * mode only. This represents the roam trigger reason for the last roaming + * attempted by the firmware. This can be queried either in connected state or + * disconnected state. Each bit of this attribute represents the different + * roam trigger reason code which are defined in enum qca_vendor_roam_triggers. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode + * only. This represents the roam fail reason for the last failed roaming + * attempt by the firmware. Different roam failure reason codes are specified + * in enum qca_vendor_roam_fail_reasons. This can be queried either in + * connected state or disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in + * STA mode only. This represents the roam invoke fail reason for the last + * failed roam invoke. Different roam invoke failure reason codes + * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be + * queried either in connected state or disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only. + * This represents the average congestion duration of uplink frames in MAC + * queue in unit of ms. This can be queried either in connected state or + * disconnected state. + */ +enum qca_wlan_vendor_attr_get_sta_info { + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC = 1, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS = 2, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL = 3, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT = 4, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED = 6, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED = 7, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL = 8, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY = 9, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED = 10, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT = 11, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT = 12, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT = 14, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT = 15, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT = 16, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT = 17, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT = 18, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT = 19, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT = 20, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT = 21, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT = 22, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT = 23, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT = 24, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT = 25, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT = 26, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS = 27, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS = 28, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0 = 29, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS = 30, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0 = 31, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT = 32, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER = 33, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER = 34, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL = 35, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_IES = 36, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PROBE_RESP_IES = 37, + QCA_WLAN_VENDOR_ATTR_GET_STA_DRIVER_DISCONNECT_REASON = 38, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT = 39, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_update_sta_info - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_CONNECT_CHANNELS: Type is NLA_UNSPEC. + * Used in STA mode. This attribute represents the list of channel center + * frequencies in MHz (u32) the station has learnt during the last connection + * or roaming attempt. This information shall not signify the channels for + * an explicit scan request from the user space. Host drivers can update this + * information to the user space in both connected and disconnected state. + * In the disconnected state this information shall signify the channels + * scanned in the last connection/roam attempt that lead to the disconnection. + */ +enum qca_wlan_vendor_attr_update_sta_info { + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_CONNECT_CHANNELS = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_disconnect_reason_codes - Specifies driver disconnect reason codes. + * Used when the driver triggers the STA to disconnect from the AP. + * + * @QCA_DISCONNECT_REASON_UNSPECIFIED: The host driver triggered the + * disconnection with the AP due to unspecified reasons. + * + * @QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE: The host driver triggered the + * disconnection with the AP due to a roaming failure. This roaming is triggered + * internally (host driver/firmware). + * + * @QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE: The driver disconnected from + * the AP when the user/external triggered roaming fails. + * + * @QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE: This reason code is used + * by the host driver whenever gateway reachability failure is detected and the + * driver disconnects with AP. + * + * @QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA: The driver disconnected from + * the AP on a channel switch announcement from it with an unsupported channel. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR: On a concurrent AP start + * with indoor channels disabled and if the STA is connected on one of these + * disabled channels, the host driver disconnected the STA with this reason + * code. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED: Disconnection due to an + * explicit request from the user to disable the current operating channel. + * + * @QCA_DISCONNECT_REASON_DEVICE_RECOVERY: STA disconnected from the AP due to + * the internal host driver/firmware recovery. + * + * @QCA_DISCONNECT_REASON_KEY_TIMEOUT: The driver triggered the disconnection on + * a timeout for the key installations from the user space. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE: The dDriver disconnected the + * STA on a band change request from the user space to a different band from the + * current operation channel/band. + * + * @QCA_DISCONNECT_REASON_IFACE_DOWN: The STA disconnected from the AP on an + * interface down trigger from the user space. + * + * @QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL: The host driver disconnected the + * STA on getting continuous transmission failures for multiple Data frames. + * + * @QCA_DISCONNECT_REASON_PEER_INACTIVITY: The STA does a keep alive + * notification to the AP by transmitting NULL/G-ARP frames. This disconnection + * represents inactivity from AP on such transmissions. + + * @QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT: This reason code is used on + * disconnection when SA Query times out (AP does not respond to SA Query). + * + * @QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE: The host driver disconnected the + * STA on missing the beacons continuously from the AP. + * + * @QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE: Disconnection due to STA not + * able to move to the channel mentioned by the AP in CSA. + * + * @QCA_DISCONNECT_REASON_USER_TRIGGERED: User triggered disconnection. + */ +enum qca_disconnect_reason_codes { + QCA_DISCONNECT_REASON_UNSPECIFIED = 0, + QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE = 1, + QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE = 2, + QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE = 3, + QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA = 4, + QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR = 5, + QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED = 6, + QCA_DISCONNECT_REASON_DEVICE_RECOVERY = 7, + QCA_DISCONNECT_REASON_KEY_TIMEOUT = 8, + QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE = 9, + QCA_DISCONNECT_REASON_IFACE_DOWN = 10, + QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL = 11, + QCA_DISCONNECT_REASON_PEER_INACTIVITY = 12, + QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT = 13, + QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE = 14, + QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE = 15, + QCA_DISCONNECT_REASON_USER_TRIGGERED = 16, +}; + +/** + * enum qca_wlan_vendor_attr_driver_disconnect_reason - Defines attributes + * used by %QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASCON_CODE: u32 attribute. + * This attribute represents the driver specific reason codes (local + * driver/firmware initiated reasons for disconnection) defined + * in enum qca_disconnect_reason_codes. + */ +enum qca_wlan_vendor_attr_driver_disconnect_reason { + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASCON_CODE = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_MAX = + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_tspec_operation - Operation of the config TSPEC request + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION. + */ +enum qca_wlan_tspec_operation { + QCA_WLAN_TSPEC_ADD = 0, + QCA_WLAN_TSPEC_DEL = 1, + QCA_WLAN_TSPEC_GET = 2, +}; + +/** + * enum qca_wlan_tspec_direction - Direction in TSPEC + * As what is defined in IEEE Std 802.11-2016, Table 9-139. + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION. + */ +enum qca_wlan_tspec_direction { + QCA_WLAN_TSPEC_DIRECTION_UPLINK = 0, + QCA_WLAN_TSPEC_DIRECTION_DOWNLINK = 1, + QCA_WLAN_TSPEC_DIRECTION_DIRECT = 2, + QCA_WLAN_TSPEC_DIRECTION_BOTH = 3, +}; + +/** + * enum qca_wlan_tspec_ack_policy - MAC acknowledgement policy in TSPEC + * As what is defined in IEEE Std 802.11-2016, Table 9-141. + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY. + */ +enum qca_wlan_tspec_ack_policy { + QCA_WLAN_TSPEC_NORMAL_ACK = 0, + QCA_WLAN_TSPEC_NO_ACK = 1, + /* Reserved */ + QCA_WLAN_TSPEC_BLOCK_ACK = 3, +}; + +/** + * enum qca_wlan_vendor_attr_config_tspec - Defines attributes + * used by %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION: + * u8 attribute. Specify the TSPEC operation of this request. Possible values + * are defined in enum qca_wlan_tspec_operation. + * Mandatory attribute for all kinds of config TSPEC requests. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_TSID: + * u8 attribute. TS ID. Possible values are 0-7. + * Applicable for operation: QCA_WLAN_TSPEC_ADD, QCA_WLAN_TSPEC_DEL, + * QCA_WLAN_TSPEC_GET. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION: + * u8 attribute. Direction of data carried by the TS. Possible values are + * defined in enum qca_wlan_tspec_direction. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_APSD: + * Flag attribute. Indicate whether APSD is enabled for the traffic associated + * with the TS. set - enabled, not set - disabled. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_USER_PRIORITY: + * u8 attribute. User priority to be used for the transport of MSDUs/A-MSDUs + * belonging to this TS. Possible values are 0-7. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY: + * u8 attribute. Indicate whether MAC acknowledgements are required for + * MPDUs/A-MSDUs belonging to this TS and the form of those acknowledgements. + * Possible values are defined in enum qca_wlan_tspec_ack_policy. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_NOMINAL_MSDU_SIZE: + * u16 attribute. Specify the nominal size in bytes of MSDUs/A-MSDUs + * belonging to this TS. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAXIMUM_MSDU_SIZE: + * u16 attribute. Specify the maximum size in bytes of MSDUs/A-MSDUs + * belonging to this TS. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MIN_SERVICE_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds between the + * start of two successive SPs. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX_SERVICE_INTERVAL: + * u32 attribute. Specify the maximum interval in microseconds between the + * start of two successive SPs. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INACTIVITY_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds that can elapse + * without arrival or transfer of an MPDU belonging to the TS before this TS + * is deleted by the MAC entity at the HC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SUSPENSION_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds that can elapse + * without arrival or transfer of an MSDU belonging to the TS before the + * generation of successive QoS(+)CF-Poll is stopped for this TS. A value of + * 0xFFFFFFFF disables the suspension interval. The value of the suspension + * interval is always less than or equal to the inactivity interval. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_DATA_RATE: + * u32 attribute. Indicate the lowest data rate in bps specified at the MAC + * SAP for transport of MSDUs or A-MSDUs belonging to this TS within the + * bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MEAN_DATA_RATE: + * u32 attribute. Indicate the average data rate in bps specified at the MAC + * SAP for transport of MSDUs or A-MSDUs belonging to this TS within the + * bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_PEAK_DATA_RATE: + * u32 attribute. Indicate the maximum allowable data rate in bps specified at + * the MAC SAP for transport of MSDUs or A-MSDUs belonging to this TS within + * the bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_BURST_SIZE: + * u32 attribute. Specify the maximum burst size in bytes of the MSDUs/A-MSDUs + * belonging to this TS that arrive at the MAC SAP at the peak data rate. A + * value of 0 indicates that there are no bursts. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_PHY_RATE: + * u32 attribute. Indicate the minimum PHY rate in bps for transport of + * MSDUs/A-MSDUs belonging to this TS within the bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SURPLUS_BANDWIDTH_ALLOWANCE: + * u16 attribute. Specify the excess allocation of time (and bandwidth) over + * and above the stated application rates required to transport an MSDU/A-MSDU + * belonging to the TS in this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + */ +enum qca_wlan_vendor_attr_config_tspec { + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_TSID = 2, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION = 3, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_APSD = 4, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_USER_PRIORITY = 5, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY = 6, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_NOMINAL_MSDU_SIZE = 7, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAXIMUM_MSDU_SIZE = 8, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MIN_SERVICE_INTERVAL = 9, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX_SERVICE_INTERVAL = 10, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INACTIVITY_INTERVAL = 11, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SUSPENSION_INTERVAL = 12, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_DATA_RATE = 13, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MEAN_DATA_RATE = 14, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_PEAK_DATA_RATE = 15, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_BURST_SIZE = 16, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_PHY_RATE = 17, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SURPLUS_BANDWIDTH_ALLOWANCE = 18, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_oci_override_frame_type - OCI override frame type + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ: SA Query Request frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP: SA Query Response frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ: FT Reassociation Request + * frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FILS_REASSOC_REQ: FILS Reassociation + * Request frame. + */ +enum qca_wlan_vendor_oci_override_frame_type { + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ = 1, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP = 2, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ = 3, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FILS_REASSOC_REQ = 4, +}; + +/** + * enum qca_wlan_vendor_attr_oci_override: Represents attributes for + * OCI override request. These attributes are used inside nested attribute + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE in QCA vendor command + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * + * @QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE: Required attribute, u8. + * Values from enum qca_wlan_vendor_oci_override_frame_type used in this + * attribute to specify the frame type in which the OCI is to be overridden. + * + * @QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY: Required (u32) + * OCI frequency (in MHz) to override in the specified frame type. + */ +enum qca_wlan_vendor_attr_oci_override { + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_MAX = + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_medium_assess_type - Type of medium assess request + * + * Values for %QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE. + */ +enum qca_wlan_medium_assess_type { + QCA_WLAN_MEDIUM_ASSESS_CCA = 0, + QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT = 1, +}; + +/** + * enum qca_wlan_vendor_attr_medium_assess - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE: + * u8 attribute. Mandatory in all kinds of medium assess requests/responses. + * Specify the type of medium assess request and indicate its type in response. + * Possible values are defined in enum qca_wlan_medium_assess_type. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_PERIOD: + * u32 attribute. Mandatory in CCA request. + * Specify the assessment period in terms of seconds. Assessment result will be + * sent as the response to the CCA request after the assessment period. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TOTAL_CYCLE_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Total timer tick count of the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IDLE_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of idle time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IBSS_RX_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of Intra BSS traffic RX time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_OBSS_RX_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of Overlapping BSS traffic RX time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX_IBSS_RSSI: + * s32 attribute. Mandatory in response to CCA request. + * Maximum RSSI of Intra BSS traffic in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MIN_IBSS_RSSI: + * s32 attribute. Mandatory in response to CCA request. + * Minimum RSSI of Intra BSS traffic in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE: + * u8 attribute. Mandatory in congestion report request. + * 1-enable 0-disable. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD: + * u8 attribute. Mandatory in congestion report enable request and will be + * ignored if present in congestion report disable request. Possible values are + * 0-100. A vendor event QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS with the type + * QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT will be sent to userspace if + * congestion percentage reaches the configured threshold. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL: + * u8 attribute. Optional in congestion report enable request and will be + * ignored if present in congestion report disable request. + * Specify the interval of congestion report event in terms of seconds. Possible + * values are 1-255. Default value 1 will be used if this attribute is omitted + * or using invalid values. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_PERCENTAGE: + * u8 attribute. Mandatory in congestion report event. + * Indicate the actual congestion percentage. Possible values are 0-100. + */ +enum qca_wlan_vendor_attr_medium_assess { + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE = 1, + + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_PERIOD = 2, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TOTAL_CYCLE_COUNT = 3, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IDLE_COUNT = 4, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IBSS_RX_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_OBSS_RX_COUNT = 6, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX_IBSS_RSSI = 7, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MIN_IBSS_RSSI = 8, + + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE = 9, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD = 10, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL = 11, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_PERCENTAGE = 12, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX = + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mbssid_tx_vdev_status - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL: + * u8 attribute. Notify the TX VDEV status. Possible values 0, 1 + * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV, + * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT: + * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID: + * u8 attribute, required. Indicates group id of Tx VDEV. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO: + * Nested attribute. This attribute shall be used by the driver to send + * group information. The attributes defined in enum + * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info + * are nested in this attribute. + */ +enum qca_wlan_vendor_attr_mbssid_tx_vdev_status { + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used + * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX: + * u32 attribute, required. Contains interface index. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS: + * u8 attribute, required. 0 - means vdev is in down state. + * 1 - means vdev is in up state. + */ +enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info { + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2, + + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1, +}; + +/** + * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies + * + * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary + * STA interface has to be given while selecting the connection policies + * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface. + * An interface is set as primary through the attribute + * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not + * applicable if the primary interface has not been set earlier. + * + * The intention is not to downgrade the primary STA performance, such as: + * - Do not reduce the number of TX/RX chains of primary connection. + * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of + * chains. + * - If using MCC, should set the MCC duty cycle of the primary connection to + * be higher than the secondary connection. + * + * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the + * subsequent STA connection shall be chosen to balance with the existing + * concurrent STA's performance. + * Such as + * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware + * capability. + * - If using MCC, set the MCC duty cycle of the primary connection to be equal + * to the secondary. + * - Prefer BSSID candidates which will help provide the best "overall" + * performance for all the STA connections. + */ +enum qca_wlan_concurrent_sta_policy_config { + QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0, + QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_concurrent_sta_policy - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG: + * u8 attribute. Configures the concurrent STA policy configuration. + * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config. + */ +enum qca_wlan_vendor_attr_concurrent_sta_policy { + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX = + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST - 1, + +}; + +/** + * enum qca_sta_connect_fail_reason_codes - Defines values carried + * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor + * attribute. + * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No Probe Response frame received + * for unicast Probe Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for + * auth request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not + * received from AP. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send + * Association Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for + * Association Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Association Response + * frame is not received from AP. + */ +enum qca_sta_connect_fail_reason_codes { + QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1, + QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7, +}; + +/** + * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different + * filters defined in this enum are used in attribute + * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK. + * + * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver + * shall filter the channels which are not usable because of coexistence with + * cellular radio. + * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver + * shall filter the channels which are not usable because of existing active + * interfaces in the driver and will result in Multi Channel Concurrency, etc. + * + */ +enum qca_wlan_vendor_usable_channels_filter { + QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0, + QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1, +}; + +/** + * enum qca_wlan_vendor_attr_chan_info - Attributes used inside + * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ: + * u32 attribute, required. Indicates the center frequency of the primary + * channel in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ: + * u32 attribute. Indicates the center frequency of the primary segment of the + * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz, + * 160 MHz, and 320 MHz channels. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ: + * u32 attribute. Indicates the center frequency of the secondary segment of + * 80+80 channel in MHz. This attribute is required only when + * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH: + * u32 attribute, required. Indicates the bandwidth of the channel, possible + * values are defined in enum nl80211_chan_width. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK: + * u32 attribute, required. Indicates all the interface types for which this + * channel is usable. This attribute encapsulates bitmasks of interface types + * defined in enum nl80211_iftype. + * + */ +enum qca_wlan_vendor_attr_chan_info { + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_usable_channels - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK: + * u32 attribute. Indicates the bands from which the channels should be reported + * in response. This attribute encapsulates bit masks of bands defined in enum + * nl80211_band. Optional attribute, if not present in the request the driver + * shall return channels from all supported bands. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK: + * u32 attribute. Indicates all the interface types for which the usable + * channels information is requested. This attribute encapsulates bitmasks of + * interface types defined in enum nl80211_iftype. Optional attribute, if not + * present in the request the driver shall send information of all supported + * interface modes. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK: + * u32 attribute. This attribute carries information of all filters that shall + * be applied while populating usable channels information by the driver. This + * attribute carries bit masks of different filters defined in enum + * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present + * in the request the driver shall send information of channels without applying + * any of the filters that can be configured through this attribute. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO: + * Nested attribute. This attribute shall be used by the driver to send + * usability information of each channel. The attributes defined in enum + * qca_wlan_vendor_attr_chan_info are used inside this attribute. + */ +enum qca_wlan_vendor_attr_usable_channels { + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX = + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history. + * + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry + * the list of radar history entries. + * Each entry contains freq, timestamp, and radar signal detect flag. + * The driver shall add an entry when CAC has finished, or radar signal + * has been detected post AP beaconing. The driver shall maintain at least + * 8 entries in order to save CAC result for a 160 MHz channel. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute. + * Channel frequency in MHz. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds. + * CLOCK_BOOTTIME timestamp when this entry is updated due to CAC + * or radar detection. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute. + * This flag indicates radar signal has been detected. + */ +enum qca_wlan_vendor_attr_radar_history { + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX = + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_mcc_quota_type: MCC channel time quota type + * + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR: In the event, it indicates that the + * target exited MCC state and cleared the quota information. In the + * command it clears MCC quota setting and restores adaptive scheduling. + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED: Channel time quota is fixed and + * will not be changed. + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC: Channel time quota is dynamic + * and the target may change the quota based on the data activity. + */ +enum qca_wlan_vendor_mcc_quota_type { + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR = 0, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED = 1, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC = 2, +}; + +/** + * enum qca_wlan_vendor_attr_mcc_quota: Used by the vendor event + * QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA to indicate MCC channel + * quota information or as a command to set the required MCC quota for an + * interface. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE: u32 attribute. + * The type is defined in enum qca_wlan_vendor_mcc_quota_type. + * In a command this specifies the MCC quota type to be set for the interface. + * In an event this provides the current quota type in force. + * This is required in a command and an event. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES: Nested attribute to carry + * the list of channel quota entries. + * In an event each entry contains the frequency and respective time quota for + * all the MCC interfaces. + * In a command it specifies the interface index and respective time quota. + * In a command only one entry (ifindex, quota pair) may be specified. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ: u32 attribute. + * Channel frequency in MHz. This is present only in an event. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE: u32 attribute. + * Channel time quota expressed as percentage. + * This is present in an event and a command. + * In an command, the user shall specify the quota to be allocated for the + * interface represented by %QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX. + * In an event this provides the existing quota for the channel. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX: u32 attribute. + * Specifies the interface index (netdev) for which the corresponding + * configurations are applied. This is required in a command only. Only one + * interface index may be specified. If not specified, the configuration is + * rejected. + */ +enum qca_wlan_vendor_attr_mcc_quota { + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES = 2, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE = 4, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX = + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag) + * Enable mDNS offload. This attribute is mandatory to enable + * mDNS offload feature. If this attribute is not present, mDNS offload + * is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing + * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This + * attribute is mandatory when enabling the feature, and not required when + * disabling the feature. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing + * the following attributes: + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute. + * It consists of a hostname and ".local" as the domain name. The character + * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes. + * It is used to compare the domain in the "QU" query. Only 1 FQDN is + * supported per vdev. + * For example: myphone.local + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required + * u16 attribute. It specifies the total number of resource records present + * in the answer section of the answer payload. This attribute is needed by the + * firmware to populate the mDNS response frame for mDNS queries without having + * to parse the answer payload. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob + * attribute sent by the mdnsResponder from userspace. It contains resource + * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This + * payload is passed down to the firmware and is transmitted in response to + * mDNS queries. + * The maximum supported size of the answer payload is 512 bytes. + */ +enum qca_wlan_vendor_attr_mdns_offload { + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_monitor_data_frame_type - Represent the various + * Data frame types to be sent over the monitor interface. + */ +enum qca_wlan_vendor_monitor_data_frame_type { + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17), +}; + +/** + * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various + * Management frame types to be sent over the monitor interface. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames + * except the Beacon frame. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected + * BSSID Beacon frames. Valid only in the connected state. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents + * the Beacon frames obtained during the scan (off channel and connected + * channel), when in connected state. + */ +enum qca_wlan_vendor_monitor_mgmt_frame_type { + QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1), + QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2), + QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3), +}; + +/** + * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various + * Control frame types to be sent over the monitor interface. + * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames + * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame + */ +enum qca_wlan_vendor_monitor_ctrl_frame_type { + QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1), +}; + +/** + * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the + * monitor mode. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Data frame types to be monitored (u32). These Data frames + * are represented by enum qca_wlan_vendor_monitor_data_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Data frame types to be monitored (u32). These Data frames + * are represented by enum qca_wlan_vendor_monitor_data_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Management frame types to be monitored (u32). These + * Management frames are represented by + * enum qca_wlan_vendor_monitor_mgmt_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Management frame types to be monitored (u32). These + * Management frames are represented by + * enum qca_wlan_vendor_monitor_mgmt_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Control frame types to be monitored (u32). These Control + * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Control frame types to be monitored (u32). These Control + * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32 + * attribute. + * Represents the interval in milliseconds only for the connected Beacon frames, + * expecting the connected BSS's Beacon frames to be sent on the monitor + * interface at this specific interval. + */ +enum qca_wlan_vendor_attr_set_monitor_mode { + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX = + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags. + * Bits will be set to 1 if the corresponding state is enabled. + * + * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start. + * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end. + */ +enum qca_wlan_vendor_roam_scan_state { + QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0), + QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1), +}; + +/** + * enum qca_wlan_vendor_roam_event_type - Roam event type flags. + * Bits will be set to 1 if the corresponding event is notified. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event + * carries the trigger reason. When set, it is expected that the roam event + * carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries + * the BSSID, RSSI, frequency info of the AP to which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event + * carries the roam fail reason. When set, it is expected that the roam event + * carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the + * BSSID, RSSI, frequency info of the AP to which the roam was attempted. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam + * event carries the roam invoke fail reason. When set, it is expected that + * the roam event carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event + * carries the roam scan state. When set, it is expected that the roam event + * carries the respective scan state via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding + * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST. + */ +enum qca_wlan_vendor_roam_event_type { + QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0), + QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1), + QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2), + QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3), +}; + +/** + * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info. + * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address + * representing the BSSID of the AP to which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value + * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is + * attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz + * on which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in + * STA mode only. This represents the roam fail reason for the last failed + * roaming attempt by the firmware for the specific BSSID. Different roam + * failure reason codes are specified in enum qca_vendor_roam_fail_reasons. + */ +enum qca_wlan_vendor_attr_roam_events_candidate_info { + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_roam_events - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the + * roam events to the driver or notify these events from the driver. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the + * driver/firmware to enable/disable the notification of roam events. It's a + * mandatory attribute and used only in the request from the userspace to the + * host driver. 1-Enable, 0-Disable. + * If the roaming is totally offloaded to the firmware, this request when + * enabled shall mandate the firmware to notify all the relevant roam events + * represented by the below attributes. If the host is in the suspend mode, + * the behavior of the firmware to notify these events is guided by + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get + * these events in the suspend state, the firmware is expected to wake up the + * host before the respective events are notified. Please note that such a + * request to get the events in the suspend state will have a definite power + * implication. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents + * that the roam events need to be notified in the suspend state too. By + * default, these roam events are notified in the resume state. With this flag, + * the roam events are notified in both resume and suspend states. + * This attribute is used in the request from the userspace to the host driver. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only. + * Represents the different roam event types, signified by the enum + * qca_wlan_vendor_roam_event_type. + * Each bit of this attribute represents the different roam even types reported + * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA + * mode only. This represents the roam trigger reason for the last roaming + * attempted by the firmware. Each bit of this attribute represents the + * different roam trigger reason code which are defined in enum + * qca_vendor_roam_triggers. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in + * STA mode only. This represents the roam invoke fail reason for the last + * failed roam invoke. Different roam invoke failure reason codes + * are specified in enum qca_vendor_roam_invoke_fail_reasons. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info + * for which the roam is attempted. Each entry is a nested attribute defined + * by enum qca_wlan_vendor_attr_roam_events_candidate_info. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents + * the scan state on which the roam events need to be notified. The values for + * this attribute are referred from enum qca_wlan_vendor_roam_scan_state. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of + * u32 values. List of frequencies in MHz considered for a roam scan. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + */ +enum qca_wlan_vendor_attr_roam_events { + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1, +}; + +/** + * enum qca_wlan_ratemask_params_type - Rate mask config type + * + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM: CCK/OFDM rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HT: HT rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT: VHT rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HE: HE rate mask config + */ +enum qca_wlan_ratemask_params_type { + QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM = 0, + QCA_WLAN_RATEMASK_PARAMS_TYPE_HT = 1, + QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT = 2, + QCA_WLAN_RATEMASK_PARAMS_TYPE_HE = 3, +}; + +/** + * enum qca_wlan_vendor_attr_ratemask_params - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG. + * This is used to set the rate mask value to be used in rate selection. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST: + * Array of nested containing attributes + * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE and + * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE: u8, represents + * the different PHY types to which the rate mask config is to be applied. + * The values for this attribute are referred from enum + * qca_wlan_vendor_ratemask_params_type. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP: binary, rate mask bitmap. + * A bit value of 1 represents rate is enabled and a value of 0 + * represents rate is disabled. + * For HE targets, 12 bits correspond to one NSS setting. + * b0-13 => NSS1, MCS 0-13 + * b14-27 => NSS2, MCS 0-13 and so on for other NSS. + * For VHT targets, 10 bits correspond to one NSS setting. + * b0-9 => NSS1, MCS 0-9 + * b10-19 => NSS2, MCS 0-9 and so on for other NSS. + * For HT targets, 8 bits correspond to one NSS setting. + * b0-7 => NSS1, MCS 0-7 + * b8-15 => NSS2, MCS 0-7 and so on for other NSS. + * For OFDM/CCK targets, 8 bits correspond to one NSS setting. + */ +enum qca_wlan_vendor_attr_ratemask_params { + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST = 1, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST - 1, +}; + +#endif /* QCA_VENDOR_H */ diff --git a/wcn6740/qcwcn/wifi_hal/radio_mode.cpp b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp new file mode 100644 index 0000000..913ddfd --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/radio_mode.cpp @@ -0,0 +1,303 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "radio_mode.h" +#include "vendor_definitions.h" +#include <netlink/genl/genl.h> +#include <string.h> +#include <net/if.h> + +/* Used to handle radio command events from driver/firmware. */ +typedef struct radio_event_handler_s { + RADIOModeCommand* mRADIOModeCommandInstance; +} radio_event_handlers; + +wifi_error initializeRadioHandler(hal_info *info) +{ + info->radio_handlers = (radio_event_handlers *)malloc( + sizeof(radio_event_handlers)); + if (info->radio_handlers) { + memset(info->radio_handlers, 0, sizeof(radio_event_handlers)); + } else { + ALOGE("%s: Allocation of radio event handlers failed", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + return WIFI_SUCCESS; +} + +wifi_error cleanupRadioHandler(hal_info *info) { + radio_event_handlers* event_handlers; + if (info && info->radio_handlers) { + event_handlers = (radio_event_handlers*) info->radio_handlers; + if (event_handlers->mRADIOModeCommandInstance) { + delete event_handlers->mRADIOModeCommandInstance; + } + memset(event_handlers, 0, sizeof(radio_event_handlers)); + free(info->radio_handlers); + info->radio_handlers = NULL; + return WIFI_SUCCESS; + } + ALOGE ("%s: info or info->radio_handlers NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; +} + +/* Used to handle radio mode command events from driver/firmware.*/ +void RADIOModeCommand::setCallbackHandler(wifi_radio_mode_change_handler handler) +{ + mHandler = handler; +} + +void RADIOModeCommand::setReqId(wifi_request_id id) +{ + mreqId = id; +} + +RADIOModeCommand::RADIOModeCommand(wifi_handle handle, int id, + u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mHandler, 0, sizeof(mHandler)); + if (registerVendorHandler(vendor_id, subcmd)) { + /* Error case should not happen print log */ + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", + __FUNCTION__, vendor_id, subcmd); + } +} + +RADIOModeCommand::~RADIOModeCommand() +{ + unregisterVendorHandler(mVendor_id, mSubcmd); +} + + +RADIOModeCommand* RADIOModeCommand::instance(wifi_handle handle, + wifi_request_id id) +{ + if (handle == NULL) { + ALOGE("Interface Handle is invalid"); + return NULL; + } + hal_info *info = getHalInfo(handle); + if (!info) { + ALOGE("hal_info is invalid"); + return NULL; + } + RADIOModeCommand* instance = info->radio_handlers->mRADIOModeCommandInstance; + if (instance) { + if (handle != getWifiHandle(instance->mInfo)) { + ALOGV("%s - Handle different, update the handle", __FUNCTION__); + instance->mInfo = (hal_info *)handle; + } + instance->setReqId(id); + } else { + info->radio_handlers->mRADIOModeCommandInstance = + new RADIOModeCommand(handle, id, OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO); + instance = info->radio_handlers->mRADIOModeCommandInstance; + } + return instance; +} + +/* This function will be the main handler for incoming event. + * Call the appropriate callback handler after parsing the vendor data. + */ +int RADIOModeCommand::handleEvent(WifiEvent &event) +{ + wifi_error ret = WIFI_SUCCESS; + int num_of_mac = 0; + wifi_mac_info mode_info; + memset(&mode_info, 0, sizeof(mode_info)); + + WifiVendorCommand::handleEvent(event); + + /* Parse the vendordata and get the attribute */ + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO: + { + struct nlattr *mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_MAX + 1]; + struct nlattr *modeInfo; + int rem; + + nla_parse(mtb_vendor, QCA_WLAN_VENDOR_ATTR_MAC_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO]) + { + for (modeInfo = (struct nlattr *) nla_data(mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO]), + rem = nla_len(mtb_vendor[QCA_WLAN_VENDOR_ATTR_MAC_INFO]); + nla_ok(modeInfo, rem);modeInfo = nla_next(modeInfo, &(rem))) { + + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX+ 1]; + nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX, + (struct nlattr *) nla_data(modeInfo), nla_len(modeInfo), NULL); + if (!tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mode_info.wlan_mac_id = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID]); + ALOGV("mac_id[%d]: %d ", num_of_mac, mode_info.wlan_mac_id); + + if (!tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND" + " NOT FOUND", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mode_info.mac_band = (wlan_mac_band) nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND]); + ALOGV("mac_band[%d]: %d ", num_of_mac, mode_info.mac_band); + + if (tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO]) + { + int num_of_iface = 0; + struct nlattr *tb_iface; + int rem_info; + + for (tb_iface = (struct nlattr *) nla_data(tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO]), + rem_info = nla_len(tb2[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO]); + nla_ok(tb_iface, rem_info);tb_iface = nla_next(tb_iface, &(rem_info))) { + + struct nlattr *tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX+ 1]; + wifi_iface_info miface_info; + + nla_parse(tb3, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX, + (struct nlattr *) nla_data(tb_iface), nla_len(tb_iface), NULL); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX" + " NOT FOUND", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + if (if_indextoname(nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX]), + miface_info.iface_name) == NULL) + { + ALOGE("%s: Failed to convert %d IFINDEX to IFNAME", __FUNCTION__, + nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX])); + } + ALOGV("ifname[%d]: %s ", num_of_iface, miface_info.iface_name); + + if (!tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ" + " NOT FOUND", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + miface_info.channel = nla_get_u32(tb3[QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ]); + ALOGV("channel[%d]: %d ", num_of_iface, miface_info.channel); + + if (!num_of_iface) + mode_info.iface_info = (wifi_iface_info *) + malloc(sizeof(wifi_iface_info)); + else + mode_info.iface_info = (wifi_iface_info *) + realloc(mode_info.iface_info, (num_of_iface + 1) * sizeof(wifi_iface_info)); + + if (mode_info.iface_info != NULL) { + memcpy(&mode_info.iface_info[num_of_iface], &miface_info, sizeof(wifi_iface_info)); + num_of_iface++; + mode_info.num_iface = num_of_iface; + } + } + } + if (!num_of_mac) + mwifi_iface_mac_info = (wifi_mac_info *) + malloc(sizeof(wifi_mac_info)); + else + mwifi_iface_mac_info = (wifi_mac_info *) + realloc(mwifi_iface_mac_info, (num_of_mac + 1) * (sizeof(wifi_mac_info))); + + if (mwifi_iface_mac_info != NULL) { + memcpy(&mwifi_iface_mac_info[num_of_mac], &mode_info, sizeof(wifi_mac_info)); + num_of_mac++; + } + } + } + + if (mHandler.on_radio_mode_change && num_of_mac) { + (*mHandler.on_radio_mode_change)(mreqId, num_of_mac, mwifi_iface_mac_info); + free(mwifi_iface_mac_info); + mwifi_iface_mac_info = NULL; + } + else { + ALOGE("No Callback registered: on radio mode change"); + free(mwifi_iface_mac_info); + mwifi_iface_mac_info = NULL; + } + } + break; + + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd); + } + + return ret; +} + +wifi_error wifi_set_radio_mode_change_handler(wifi_request_id id, + wifi_interface_handle iface, + wifi_radio_mode_change_handler eh) +{ + wifi_error ret; + WifiVendorCommand *vCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + RADIOModeCommand *radiomodeCommand; + + ret = initialize_vendor_cmd(iface, id, + QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + radiomodeCommand = RADIOModeCommand::instance(wifiHandle, id); + if (radiomodeCommand == NULL) { + ALOGE("%s: Error RadioModeCommand NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + radiomodeCommand->setCallbackHandler(eh); + radiomodeCommand->setReqId(id); + +cleanup: + delete vCommand; + return mapKernelErrortoWifiHalError(ret); +} diff --git a/wcn6740/qcwcn/wifi_hal/radio_mode.h b/wcn6740/qcwcn/wifi_hal/radio_mode.h new file mode 100644 index 0000000..d6a4e92 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/radio_mode.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2017-2018, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_RADIO_MODE_COMMAND_H__ +#define __WIFI_HAL_RADIO_MODE_COMMAND_H__ + +#include "cpp_bindings.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +class RADIOModeCommand: public WifiVendorCommand +{ +private: + static RADIOModeCommand *mRADIOModeCommandInstance; + wifi_radio_mode_change_handler mHandler; + wifi_request_id mreqId; + wifi_mac_info *mwifi_iface_mac_info; + RADIOModeCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + +public: + virtual ~RADIOModeCommand(); + static RADIOModeCommand* instance(wifi_handle handle, wifi_request_id id); + virtual int handleEvent(WifiEvent &event); + virtual void setReqId(wifi_request_id reqid); + virtual void setCallbackHandler(wifi_radio_mode_change_handler nHandler); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp b/wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp new file mode 100644 index 0000000..9083725 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp @@ -0,0 +1,166 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include <stdint.h> +#include <stdlib.h> + +#include "sync.h" +#include "wifi_hal.h" +#include "common.h" + +#include "ring_buffer.h" +#include "rb_wrapper.h" + +#define LOG_TAG "WifiHAL" + +wifi_error rb_init(hal_info *info, struct rb_info *rb_info, int id, + size_t size_of_buf, int num_bufs, char *name) +{ + rb_info->rb_ctx = ring_buffer_init(size_of_buf, num_bufs); + if (rb_info->rb_ctx == NULL) { + ALOGE("Failed to init ring buffer"); + return WIFI_ERROR_OUT_OF_MEMORY; + } + strlcpy(rb_info->name, name, MAX_RB_NAME_SIZE); + rb_info->ctx = info; + rb_info->id = id; + + /* Initialize last_push_time */ + gettimeofday(&rb_info->last_push_time, NULL); + return WIFI_SUCCESS; +} + +void rb_deinit(struct rb_info *rb_info) +{ + if (rb_info->rb_ctx) { + ring_buffer_deinit(rb_info->rb_ctx); + rb_info->rb_ctx = NULL; + } + rb_info->name[0] = '\0'; +} + +void get_rb_status(struct rb_info *rb_info, wifi_ring_buffer_status *rbs) +{ + struct rb_stats rb_stats; + + strlcpy((char *)rbs->name, rb_info->name, MAX_RB_NAME_SIZE); + rbs->flags = rb_info->flags; + rbs->ring_id = rb_info->id; + rbs->verbose_level = rb_info->verbose_level; + rb_get_stats(rb_info->rb_ctx, &rb_stats); + rbs->ring_buffer_byte_size = rb_stats.max_num_bufs * + rb_stats.each_buf_size; + rbs->written_bytes = rb_stats.total_bytes_written; + rbs->read_bytes = rb_stats.total_bytes_read; + rbs->written_records = rb_info->written_records; +} + +int is_rb_name_match(struct rb_info *rb_info, char *name) +{ + return (strncmp(rb_info->name, name, MAX_RB_NAME_SIZE) == 0); +} + +wifi_error ring_buffer_write(struct rb_info *rb_info, u8 *buf, size_t length, + int no_of_records, size_t record_length) +{ + enum rb_status status; + + status = rb_write(rb_info->rb_ctx, buf, length, 0, record_length); + if ((status == RB_FULL) || (status == RB_RETRY)) { + push_out_rb_data(rb_info); + /* Try writing the data after reading it out */ + status = rb_write(rb_info->rb_ctx, buf, length, 0, record_length); + if (status != RB_SUCCESS) { + ALOGE("Failed to rewrite %zu bytes to rb %s with error %d", length, + rb_info->name, status); + return WIFI_ERROR_UNKNOWN; + } + } else if (status == RB_FAILURE) { + ALOGE("Failed to write %zu bytes to rb %s with error %d", length, + rb_info->name, status); + return WIFI_ERROR_UNKNOWN; + } + + if (rb_info->written_records < (UINT_MAX - 1)) + rb_info->written_records += no_of_records; + else + rb_info->written_records = 0; + + return WIFI_SUCCESS; +} + +void push_out_rb_data(void *cb_ctx) +{ + struct rb_info *rb_info = (struct rb_info *)cb_ctx; + hal_info *info = (hal_info *)rb_info->ctx; + wifi_ring_buffer_status rbs; + wifi_ring_buffer_data_handler handler; + + while (info && !info->clean_up) { + size_t length = 0; + u8 *buf; + + buf = rb_get_read_buf(rb_info->rb_ctx, &length); + if (buf == NULL) { + break; + } + get_rb_status(rb_info, &rbs); + pthread_mutex_lock(&info->lh_lock); + handler.on_ring_buffer_data = info->on_ring_buffer_data; + pthread_mutex_unlock(&info->lh_lock); + if (handler.on_ring_buffer_data) { + handler.on_ring_buffer_data(rb_info->name, (char *)buf, + length, &rbs); + } + free(buf); + }; + gettimeofday(&rb_info->last_push_time, NULL); +} + +wifi_error rb_start_logging(struct rb_info *rb_info, u32 verbose_level, + u32 flags, u32 max_interval_sec, u32 min_data_size) +{ + rb_info->verbose_level = verbose_level; + rb_info->flags = flags; + rb_info->max_interval_sec = max_interval_sec; + + rb_config_threshold(rb_info->rb_ctx, min_data_size, push_out_rb_data, rb_info); + return WIFI_SUCCESS; +} + +void rb_check_for_timeout(struct rb_info *rb_info, struct timeval *now) +{ + if (rb_info->max_interval_sec == 0) { + return; + } + if (now->tv_sec >= + (rb_info->last_push_time.tv_sec + + (__kernel_time_t)rb_info->max_interval_sec)) { + push_out_rb_data(rb_info); + } +} diff --git a/wcn6740/qcwcn/wifi_hal/rb_wrapper.h b/wcn6740/qcwcn/wifi_hal/rb_wrapper.h new file mode 100644 index 0000000..6160ebc --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/rb_wrapper.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __RB_WRAPPER_H +#define __RB_WRAPPER_H + +#define MAX_RB_NAME_SIZE 32 + +struct rb_info { + void *rb_ctx; + char name[MAX_RB_NAME_SIZE]; + u32 flags; + u32 verbose_level; + u32 written_records; + u32 max_interval_sec; + int id; + void *ctx; + struct timeval last_push_time; +}; +struct hal_info_s; +wifi_error rb_init(struct hal_info_s *info, struct rb_info *rb_info, int id, + size_t size_of_buf, int num_bufs, char *name); +void rb_deinit(struct rb_info *rb_info); +void get_rb_status(struct rb_info *rb_info, wifi_ring_buffer_status *rbs); +void rb_check_for_timeout(struct rb_info *rb_info, struct timeval *now); +wifi_error rb_start_logging(struct rb_info *rb_info, u32 verbose_level, + u32 flags, u32 max_interval_sec, u32 min_data_size); +int is_rb_name_match(struct rb_info *rb_info, char *name); +wifi_error ring_buffer_write(struct rb_info *rb_info, u8 *buf, size_t length, + int no_of_records, size_t record_length); +void push_out_rb_data(void *cb_ctx); +#endif /* __RB_WRAPPER_H */ diff --git a/wcn6740/qcwcn/wifi_hal/ring_buffer.cpp b/wcn6740/qcwcn/wifi_hal/ring_buffer.cpp new file mode 100644 index 0000000..5918923 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/ring_buffer.cpp @@ -0,0 +1,607 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +typedef unsigned char u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +#include "ring_buffer.h" + +enum rb_bool { + RB_TRUE = 0, + RB_FALSE = 1 +}; + +typedef struct rb_entry_s { + u8 *data; + unsigned int last_wr_index; + u8 full; +} rb_entry_t; + +typedef struct ring_buf_cb { + unsigned int rd_buf_no; // Current buffer number to be read from + unsigned int wr_buf_no; // Current buffer number to be written into + unsigned int cur_rd_buf_idx; // Read index within the current read buffer + unsigned int cur_wr_buf_idx; // Write index within the current write buffer + rb_entry_t *bufs; // Array of buffer pointers + + unsigned int max_num_bufs; // Maximum number of buffers that should be used + size_t each_buf_size; // Size of each buffer in bytes + + pthread_mutex_t rb_rw_lock; + + /* Threshold vars */ + unsigned int num_min_bytes; + void (*threshold_cb)(void *); + void *cb_ctx; + + u64 total_bytes_written; + u64 total_bytes_read; + u64 total_bytes_overwritten; + u32 cur_valid_bytes; + enum rb_bool threshold_reached; +} rbc_t; + + +#define RB_MIN(x, y) ((x) < (y)?(x):(y)) +inline void rb_lock(pthread_mutex_t *lock) +{ + int error = pthread_mutex_lock(lock); + + if (error) + ALOGE("Failed to acquire lock with err %d", error); + // TODO Handle the lock failure +} + +inline void rb_unlock(pthread_mutex_t *lock) +{ + int error = pthread_mutex_unlock(lock); + + if (error) + ALOGE("Failed to release lock with err %d", error); + // TODO Handle the unlock failure +} + +void * ring_buffer_init(size_t size_of_buf, int num_bufs) +{ + struct ring_buf_cb *rbc; + int status; + + rbc = (struct ring_buf_cb *)malloc(sizeof(struct ring_buf_cb)); + if (rbc == NULL) { + ALOGE("Failed to alloc rbc"); + return NULL; + } + memset(rbc, 0, sizeof(struct ring_buf_cb)); + + rbc->bufs = (rb_entry_t *)malloc(num_bufs * sizeof(rb_entry_t)); + if (rbc->bufs == NULL) { + free(rbc); + ALOGE("Failed to alloc rbc->bufs"); + return NULL; + } + memset(rbc->bufs, 0, (num_bufs * sizeof(rb_entry_t))); + + rbc->each_buf_size = size_of_buf; + rbc->max_num_bufs = num_bufs; + + status = pthread_mutex_init(&rbc->rb_rw_lock, NULL); + if (status != 0) { + ALOGE("Failed to initialize rb_rw_lock"); + // TODO handle lock initialization failure + } + rbc->threshold_reached = RB_FALSE; + return rbc; +} + +void ring_buffer_deinit(void *ctx) +{ + rbc_t *rbc = (rbc_t *)ctx; + int status; + unsigned int buf_no; + + status = pthread_mutex_destroy(&rbc->rb_rw_lock); + if (status != 0) { + ALOGE("Failed to destroy rb_rw_lock"); + // TODO handle the lock destroy failure + } + for (buf_no = 0; buf_no < rbc->max_num_bufs; buf_no++) { + free(rbc->bufs[buf_no].data); + } + free(rbc->bufs); + free(rbc); +} + +/* + * record_length : 0 - byte boundary + * : >0 - Ensures to write record_length no.of bytes to the same buffer. + */ +enum rb_status rb_write (void *ctx, u8 *buf, size_t length, int overwrite, + size_t record_length) +{ + rbc_t *rbc = (rbc_t *)ctx; + unsigned int bytes_written = 0; // bytes written into rb so far + unsigned int push_in_rd_ptr = 0; // push required in read pointer because of + // write in current buffer + unsigned int total_push_in_rd_ptr = 0; // Total amount of push in read pointer in this write + + if (record_length > rbc->each_buf_size || length > rbc->each_buf_size) { + return RB_FAILURE; + } + + if (overwrite == 0) { + /* Check if the complete RB is full. If the current wr_buf is also + * full, it indicates that the complete RB is full + */ + if (rbc->bufs[rbc->wr_buf_no].full == 1) + return RB_FULL; + /* Check whether record fits in current buffer */ + if (rbc->wr_buf_no == rbc->rd_buf_no) { + if ((rbc->cur_wr_buf_idx == rbc->cur_rd_buf_idx) && + rbc->cur_valid_bytes) { + return RB_FULL; + } else if (rbc->cur_wr_buf_idx < rbc->cur_rd_buf_idx) { + if (record_length > + (rbc->cur_rd_buf_idx - rbc->cur_wr_buf_idx)) { + return RB_FULL; + } + } else { + if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + /* Check if the next buffer is not full to write this record into + * next buffer + */ + unsigned int next_buf_no = rbc->wr_buf_no + 1; + + if (next_buf_no >= rbc->max_num_bufs) { + next_buf_no = 0; + } + if (rbc->bufs[next_buf_no].full == 1) { + return RB_FULL; + } + } + } + } else if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + /* Check if the next buffer is not full to write this record into + * next buffer + */ + unsigned int next_buf_no = rbc->wr_buf_no + 1; + + if (next_buf_no >= rbc->max_num_bufs) { + next_buf_no = 0; + } + if (rbc->bufs[next_buf_no].full == 1) { + return RB_FULL; + } + } + } + + /* Go to next buffer if the current buffer is not enough to write the + * complete record + */ + if (record_length > (rbc->each_buf_size - rbc->cur_wr_buf_idx)) { + rbc->bufs[rbc->wr_buf_no].full = 1; + rbc->bufs[rbc->wr_buf_no].last_wr_index = rbc->cur_wr_buf_idx; + rbc->wr_buf_no++; + if (rbc->wr_buf_no == rbc->max_num_bufs) { + rbc->wr_buf_no = 0; + } + rbc->cur_wr_buf_idx = 0; + } + + + /* In each iteration of below loop, the data that can be fit into + * buffer @wr_buf_no will be copied from input buf */ + while (bytes_written < length) { + unsigned int cur_copy_len; + + /* Allocate a buffer if no buf available @ wr_buf_no */ + if (rbc->bufs[rbc->wr_buf_no].data == NULL) { + rbc->bufs[rbc->wr_buf_no].data = (u8 *)malloc(rbc->each_buf_size); + if (rbc->bufs[rbc->wr_buf_no].data == NULL) { + ALOGE("Failed to alloc write buffer"); + return RB_RETRY; + } + } + + /* Take the minimum of the remaining length that needs to be written + * from buf and the maximum length that can be written into current + * buffer in ring buffer + */ + cur_copy_len = RB_MIN((rbc->each_buf_size - rbc->cur_wr_buf_idx), + (length - bytes_written)); + + rb_lock(&rbc->rb_rw_lock); + + /* Push the read pointer in case of overrun */ + if (rbc->rd_buf_no == rbc->wr_buf_no) { + if ((rbc->cur_rd_buf_idx > rbc->cur_wr_buf_idx) || + ((rbc->cur_rd_buf_idx == rbc->cur_wr_buf_idx) && + rbc->cur_valid_bytes)) { + /* If read ptr is ahead of write pointer and if the + * gap is not enough to fit the cur_copy_len bytes then + * push the read pointer so that points to the start of + * old bytes after this write + */ + if ((rbc->cur_rd_buf_idx - rbc->cur_wr_buf_idx) < + cur_copy_len) { + push_in_rd_ptr += cur_copy_len - + (rbc->cur_rd_buf_idx - rbc->cur_wr_buf_idx); + rbc->cur_rd_buf_idx = rbc->cur_wr_buf_idx + cur_copy_len; + if (rbc->cur_rd_buf_idx >= + rbc->bufs[rbc->rd_buf_no].last_wr_index) { + rbc->cur_rd_buf_idx = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + rbc->rd_buf_no = 0; + ALOGV("Pushing read to the start of ring buffer"); + } + /* the previous buffer might have little more empty room + * after overwriting the remaining bytes + */ + rbc->bufs[rbc->wr_buf_no].full = 0; + } + } + } + } + rb_unlock(&rbc->rb_rw_lock); + if(rbc->bufs[rbc->wr_buf_no].data == NULL || (rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx) == NULL || + buf == NULL || buf + bytes_written == NULL) { + ALOGE("The read or Write buffer is null"); + return RB_FAILURE; + } + if (((bytes_written + cur_copy_len) > length + || (rbc->cur_wr_buf_idx + cur_copy_len) > rbc->each_buf_size)) { + ALOGE("LOG_RB rb_write overflow - cur_copy_len=%d wr_buf[max=%zu no=%d idx=%d] buf[max=%zu accessed=%d]", + cur_copy_len, rbc->each_buf_size, rbc->wr_buf_no, rbc->cur_wr_buf_idx, length, bytes_written + cur_copy_len); + return RB_FAILURE; + } + + /* don't use lock while doing memcpy, so that we don't block the read + * context for too long. There is no harm while writing the memory if + * locking is properly done while upgrading the pointers */ + memcpy((rbc->bufs[rbc->wr_buf_no].data + rbc->cur_wr_buf_idx), + (buf + bytes_written), + cur_copy_len); + + rb_lock(&rbc->rb_rw_lock); + /* Update the write idx by the amount of write done in this iteration */ + rbc->cur_wr_buf_idx += cur_copy_len; + if (rbc->cur_wr_buf_idx == rbc->each_buf_size) { + /* Increment the wr_buf_no as the current buffer is full */ + rbc->bufs[rbc->wr_buf_no].full = 1; + rbc->bufs[rbc->wr_buf_no].last_wr_index = rbc->cur_wr_buf_idx; + rbc->wr_buf_no++; + if (rbc->wr_buf_no == rbc->max_num_bufs) { + ALOGV("Write rolling over to the start of ring buffer"); + rbc->wr_buf_no = 0; + } + /* Reset the write index to zero as this is a new buffer */ + rbc->cur_wr_buf_idx = 0; + } + + if ((rbc->cur_valid_bytes + (cur_copy_len - push_in_rd_ptr)) > + (rbc->max_num_bufs * rbc->each_buf_size)) { + /* The below is only a precautionary print and ideally should never + * come */ + ALOGE("Something going wrong in ring buffer"); + } else { + /* Increase the valid bytes count by number of bytes written without + * overwriting the old bytes */ + rbc->cur_valid_bytes += cur_copy_len - push_in_rd_ptr; + } + total_push_in_rd_ptr += push_in_rd_ptr; + push_in_rd_ptr = 0; + rb_unlock(&rbc->rb_rw_lock); + bytes_written += cur_copy_len; + } + + rb_lock(&rbc->rb_rw_lock); + rbc->total_bytes_written += bytes_written - total_push_in_rd_ptr; + rbc->total_bytes_overwritten += total_push_in_rd_ptr; + + /* check if valid bytes is going more than threshold */ + if ((rbc->threshold_reached == RB_FALSE) && + (rbc->cur_valid_bytes >= rbc->num_min_bytes) && + ((length == record_length) || !record_length) && + rbc->threshold_cb) { + /* Release the lock before calling threshold_cb as it might call rb_read + * in this same context in order to avoid dead lock + */ + rbc->threshold_reached = RB_TRUE; + rb_unlock(&rbc->rb_rw_lock); + rbc->threshold_cb(rbc->cb_ctx); + } else { + rb_unlock(&rbc->rb_rw_lock); + } + return RB_SUCCESS; +} + +size_t rb_read (void *ctx, u8 *buf, size_t max_length) +{ + rbc_t *rbc = (rbc_t *)ctx; + unsigned int bytes_read = 0; + unsigned int no_more_bytes_available = 0; + + rb_lock(&rbc->rb_rw_lock); + while (bytes_read < max_length) { + unsigned int cur_cpy_len; + + if (rbc->bufs[rbc->rd_buf_no].data == NULL) { + break; + } + + /* if read and write are on same buffer, work with rd, wr indices */ + if (rbc->rd_buf_no == rbc->wr_buf_no) { + if (rbc->cur_rd_buf_idx < rbc->cur_wr_buf_idx) { + /* Check if all the required bytes are available, if not + * read only the available bytes in the current buffer and + * break out after reading current buffer + */ + if ((rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx) < + (max_length - bytes_read)) { + cur_cpy_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx; + no_more_bytes_available = 1; + } else { + cur_cpy_len = max_length - bytes_read; + } + } else { + /* When there are no bytes available to read cur_rd_buf_idx + * will be euqal to cur_wr_buf_idx. Handle this scenario using + * cur_valid_bytes */ + if (rbc->cur_valid_bytes <= bytes_read) { + /* Suppress possible static analyzer's warning */ + cur_cpy_len = 0; + break; + } + cur_cpy_len = RB_MIN((rbc->each_buf_size - rbc->cur_rd_buf_idx), + (max_length - bytes_read)); + } + } else { + /* Check if all remaining_length bytes can be read from this + * buffer, if not read only the available bytes in the current + * buffer and go to next buffer using the while loop. + */ + cur_cpy_len = RB_MIN((rbc->each_buf_size - rbc->cur_rd_buf_idx), + (max_length - bytes_read)); + } + + memcpy((buf + bytes_read), + (rbc->bufs[rbc->rd_buf_no].data + rbc->cur_rd_buf_idx), + cur_cpy_len); + + /* Update the read index */ + rbc->cur_rd_buf_idx += cur_cpy_len; + if (rbc->cur_rd_buf_idx == rbc->each_buf_size) { + /* Increment rd_buf_no as the current buffer is completely read */ + if (rbc->rd_buf_no != rbc->wr_buf_no) { + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; + } + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + ALOGV("Read rolling over to the start of ring buffer"); + rbc->rd_buf_no = 0; + } + /* Reset the read index as this is a new buffer */ + rbc->cur_rd_buf_idx = 0; + } + + bytes_read += cur_cpy_len; + if (no_more_bytes_available) { + break; + } + } + + rbc->total_bytes_read += bytes_read; + if (rbc->cur_valid_bytes < bytes_read) { + /* The below is only a precautionary print and ideally should never + * come */ + ALOGE("Something going wrong in ring buffer"); + } else { + rbc->cur_valid_bytes -= bytes_read; + } + + /* check if valid bytes is going less than threshold */ + if (rbc->threshold_reached == RB_TRUE) { + if (rbc->cur_valid_bytes < rbc->num_min_bytes) { + rbc->threshold_reached = RB_FALSE; + } + } + rb_unlock(&rbc->rb_rw_lock); + return bytes_read; +} + +u8 *rb_get_read_buf(void *ctx, size_t *length) +{ + rbc_t *rbc = (rbc_t *)ctx; + unsigned int cur_read_len = 0; + u8 *buf; + + /* If no buffer is available for reading */ + if (!rbc || rbc->bufs[rbc->rd_buf_no].data == NULL) { + *length = 0; + return NULL; + } + + rb_lock(&rbc->rb_rw_lock); + if ((rbc->bufs[rbc->rd_buf_no].full == 1) && + (rbc->cur_rd_buf_idx == rbc->bufs[rbc->rd_buf_no].last_wr_index)) { + if (rbc->wr_buf_no != rbc->rd_buf_no) { + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; + } + rbc->bufs[rbc->rd_buf_no].full = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + rbc->rd_buf_no = 0; + } + rbc->cur_rd_buf_idx = 0; + } + + if (rbc->wr_buf_no == rbc->rd_buf_no) { + /* If read and write are happening on the same buffer currently, use + * rd and wr indices within the buffer */ + if ((rbc->cur_rd_buf_idx == rbc->cur_wr_buf_idx) && + (rbc->cur_valid_bytes == 0)) { + /* No bytes available for reading */ + *length = 0; + rb_unlock(&rbc->rb_rw_lock); + return NULL; + } else if (rbc->cur_rd_buf_idx < rbc->cur_wr_buf_idx) { + /* write is just ahead of read in this buffer */ + cur_read_len = rbc->cur_wr_buf_idx - rbc->cur_rd_buf_idx; + } else { + /* write is rolled over and just behind the read */ + if (rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) { + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx; + } else { + ALOGE("Alert: cur_read_len=%u invalid, rd_buf[no=%d rd_idx=%d wr_index=%d]",cur_read_len, rbc->rd_buf_no, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index); + rb_unlock(&rbc->rb_rw_lock); + return NULL; + } + } + } else { + if (rbc->cur_rd_buf_idx == 0) { + /* The complete buffer can be read out */ + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index; + } else { + if ( rbc->bufs[rbc->rd_buf_no].last_wr_index >= rbc->cur_rd_buf_idx) { + /* Read the remaining bytes in this buffer */ + cur_read_len = rbc->bufs[rbc->rd_buf_no].last_wr_index - rbc->cur_rd_buf_idx; + } + else { + ALOGE("Alert: cur_read_len invalid cur_read_len = %u, cur_rd_buf_idx = %u, last_write_index = %u, read_buf_no = %u, max_num_bufs = %u", cur_read_len, rbc->cur_rd_buf_idx, rbc->bufs[rbc->rd_buf_no].last_wr_index, rbc->rd_buf_no,rbc->max_num_bufs); + /* Move to the next buffer */ + rbc->bufs[rbc->rd_buf_no].full = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + ALOGV("Read rolling over to the start of ring buffer"); + rbc->rd_buf_no = 0; + } + } + } + } + + if ((rbc->bufs[rbc->rd_buf_no].full == 1) && + (rbc->cur_rd_buf_idx == 0)) { + /* Pluck out the complete buffer and send it out */ + buf = rbc->bufs[rbc->rd_buf_no].data; + rbc->bufs[rbc->rd_buf_no].data = NULL; + + /* Move to the next buffer */ + rbc->bufs[rbc->rd_buf_no].full = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + ALOGV("Read rolling over to the start of ring buffer"); + rbc->rd_buf_no = 0; + } + } else { + /* We cannot give out the complete buffer, so allocate a new memory and + * and copy the data into it. + */ + buf = (u8 *)malloc(cur_read_len); + if (buf == NULL) { + ALOGE("Failed to alloc buffer for partial buf read"); + *length = 0; + rb_unlock(&rbc->rb_rw_lock); + return NULL; + } + memcpy(buf, + (rbc->bufs[rbc->rd_buf_no].data + rbc->cur_rd_buf_idx), + cur_read_len); + + /* Update the read index */ + if (rbc->bufs[rbc->rd_buf_no].full == 1) { + if (rbc->wr_buf_no != rbc->rd_buf_no) { + free(rbc->bufs[rbc->rd_buf_no].data); + rbc->bufs[rbc->rd_buf_no].data = NULL; + } + rbc->bufs[rbc->rd_buf_no].full = 0; + rbc->rd_buf_no++; + if (rbc->rd_buf_no == rbc->max_num_bufs) { + rbc->rd_buf_no = 0; + } + rbc->cur_rd_buf_idx = 0; + } else { + rbc->cur_rd_buf_idx += cur_read_len; + } + } + + rbc->total_bytes_read += cur_read_len; + if (rbc->cur_valid_bytes < cur_read_len) { + /* The below is only a precautionary print and ideally should never + * come */ + ALOGE("Something going wrong in ring buffer"); + } else { + rbc->cur_valid_bytes -= cur_read_len; + } + + /* check if valid bytes is going less than threshold */ + if (rbc->threshold_reached == RB_TRUE) { + if (rbc->cur_valid_bytes < rbc->num_min_bytes) { + rbc->threshold_reached = RB_FALSE; + } + } + rb_unlock(&rbc->rb_rw_lock); + + *length = cur_read_len; + return buf; +} + +void rb_config_threshold(void *ctx, + unsigned int num_min_bytes, + threshold_call_back callback, + void *cb_ctx) +{ + rbc_t *rbc = (rbc_t *)ctx; + + rbc->num_min_bytes = num_min_bytes; + rbc->threshold_cb = callback; + rbc->cb_ctx = cb_ctx; +} + +void rb_get_stats(void *ctx, struct rb_stats *rbs) +{ + rbc_t *rbc = (rbc_t *)ctx; + + rbs->total_bytes_written = rbc->total_bytes_written; + rbs->total_bytes_read = rbc->total_bytes_read; + rbs->cur_valid_bytes = rbc->cur_valid_bytes; + rbs->each_buf_size = rbc->each_buf_size; + rbs->max_num_bufs = rbc->max_num_bufs; +} diff --git a/wcn6740/qcwcn/wifi_hal/ring_buffer.h b/wcn6740/qcwcn/wifi_hal/ring_buffer.h new file mode 100644 index 0000000..3a310b7 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/ring_buffer.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __RING_BUFFER_H +#define __RING_BUFFER_H + +/* Ring buffer status codes */ +enum rb_status { + RB_SUCCESS = 0, + RB_FAILURE = 1, + RB_FULL = 2, + RB_RETRY = 3, +}; + +struct rb_stats { + u32 total_bytes_written; + u32 total_bytes_read; + u32 cur_valid_bytes; + unsigned int max_num_bufs; + size_t each_buf_size; +}; + +typedef void (*threshold_call_back) (void *cb_ctx); + +/* intiitalizes the ring buffer and returns the context to it */ +void * ring_buffer_init(size_t size_of_buf, int num_bufs); + +/* Frees up the mem allocated for this ring buffer operation */ +void ring_buffer_deinit(void *ctx); + +/* Writes writes length of bytes from buf to ring buffer */ +enum rb_status rb_write(void *ctx, u8 *buf, size_t length, int overwrite, + size_t record_length); + +/* Tries to read max_length of bytes from ring buffer to buf + * and returns actual length of bytes read from ring buffer + */ +size_t rb_read(void *ctx, u8 *buf, size_t max_length); + +/* A buffer with possible maximum of bytes that can be read + * from a single buffer of ring buffer + * Ring buffer module looses the ownership of the buffer returned by this api, + * which means the caller has to make sure to free the buffer returned. + */ +u8 *rb_get_read_buf(void *ctx, size_t *length); + +/* calls callback whenever ring_buffer reaches percent percentage of it'ss + * full size + */ +void rb_config_threshold(void *ctx, + unsigned int num_min_bytes, + threshold_call_back callback, + void *cb_ctx); + +/* Get the current status of ring buffer */ +void rb_get_stats(void *ctx, struct rb_stats *rbs); + +#endif /* __RING_BUFFER_H */ diff --git a/wcn6740/qcwcn/wifi_hal/roam.cpp b/wcn6740/qcwcn/wifi_hal/roam.cpp new file mode 100644 index 0000000..595fc60 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/roam.cpp @@ -0,0 +1,412 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <errno.h> + +#include "common.h" +#include "roamcommand.h" + +#define WLAN_ROAM_MAX_NUM_WHITE_LIST 8 +#define WLAN_ROAM_MAX_NUM_BLACK_LIST 16 + +RoamCommand::RoamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ +} + +RoamCommand::~RoamCommand() +{ +} + +/* This function implements creation of Vendor command */ +wifi_error RoamCommand::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + return ret; + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + if (ret != WIFI_SUCCESS) + return ret; + + ALOGV("%s: mVendor_id = %d, Subcmd = %d.", + __FUNCTION__, mVendor_id, mSubcmd); + return ret; +} + +wifi_error RoamCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +wifi_error wifi_set_bssid_blacklist(wifi_request_id id, + wifi_interface_handle iface, + wifi_bssid_params params) +{ + wifi_error ret; + int i; + RoamCommand *roamCommand; + struct nlattr *nlData, *nlBssids; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (!(info->supported_feature_set & WIFI_FEATURE_CONTROL_ROAMING)) { + ALOGE("%s: Roaming is not supported by driver", + __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + for (i = 0; i < params.num_bssid; i++) { + ALOGV("BSSID: %d : %02x:%02x:%02x:%02x:%02x:%02x", i, + params.bssids[i][0], params.bssids[i][1], + params.bssids[i][2], params.bssids[i][3], + params.bssids[i][4], params.bssids[i][5]); + } + + roamCommand = + new RoamCommand(wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_ROAM); + if (roamCommand == NULL) { + ALOGE("%s: Error roamCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = roamCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = roamCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = roamCommand->put_u32( QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = roamCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID, + params.num_bssid); + if (ret != WIFI_SUCCESS) + goto cleanup; + + nlBssids = roamCommand->attr_start( + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS); + for (i = 0; i < params.num_bssid; i++) { + struct nlattr *nl_ssid = roamCommand->attr_start(i); + + ret = roamCommand->put_addr( + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID, + (u8 *)params.bssids[i]); + if (ret != WIFI_SUCCESS) + goto cleanup; + + roamCommand->attr_end(nl_ssid); + } + roamCommand->attr_end(nlBssids); + + roamCommand->attr_end(nlData); + + ret = roamCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("wifi_set_bssid_blacklist(): requestResponse Error:%d", ret); + +cleanup: + delete roamCommand; + return ret; + +} + +wifi_error wifi_set_ssid_white_list(wifi_request_id id, wifi_interface_handle iface, + int num_networks, ssid_t *ssid_list) +{ + wifi_error ret; + int i; + RoamCommand *roamCommand; + struct nlattr *nlData, *nlSsids; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + char ssid[MAX_SSID_LENGTH + 1]; + + ALOGV("%s: Number of SSIDs : %d", __FUNCTION__, num_networks); + + roamCommand = new RoamCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_ROAM); + if (roamCommand == NULL) { + ALOGE("%s: Failed to create object of RoamCommand class", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = roamCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create NL message, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = roamCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + goto cleanup; + } + + ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, id); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS, + num_networks); + if (ret != WIFI_SUCCESS) + goto cleanup; + + nlSsids = roamCommand->attr_start(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST); + for (i = 0; i < num_networks; i++) { + struct nlattr *nl_ssid = roamCommand->attr_start(i); + + memcpy(ssid, ssid_list[i].ssid_str, ssid_list[i].length); + ssid[ssid_list[i].length] = '\0'; + ALOGV("ssid[%d] : %s", i, ssid); + + ret = roamCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID, + ssid, (ssid_list[i].length + 1)); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to add ssid atribute, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + roamCommand->attr_end(nl_ssid); + } + roamCommand->attr_end(nlSsids); + + roamCommand->attr_end(nlData); + + ret = roamCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret); + +cleanup: + delete roamCommand; + return ret; +} + +wifi_error wifi_get_roaming_capabilities(wifi_interface_handle iface, + wifi_roaming_capabilities *caps) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (!caps) { + ALOGE("%s: Invalid Buffer provided. Exit", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (!info) { + ALOGE("%s: hal_info is NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + // Per WiFi HAL design, roaming feature should have nothing to do with Gscan + // But for current driver impl, roaming_capa is provided as part of + // GSCAN_GET_CAPABILITY query, so if Gscan is not supported, roaming_capa + // is not set (uses initial value 0). + // To de-couple roaming with Gscan, set default values for roaming_capa + // if Gscan is not supported. + // TODO: removes below if driver has new API to get roaming_capa. + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + info->capa.roaming_capa.max_whitelist_size = WLAN_ROAM_MAX_NUM_WHITE_LIST; + info->capa.roaming_capa.max_blacklist_size = WLAN_ROAM_MAX_NUM_BLACK_LIST; + } + memcpy(caps, &info->capa.roaming_capa, sizeof(wifi_roaming_capabilities)); + + return WIFI_SUCCESS; +} + +wifi_error wifi_configure_roaming(wifi_interface_handle iface, wifi_roaming_config *roaming_config) +{ + wifi_error ret; + int requestId; + wifi_bssid_params bssid_params; + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (!roaming_config) { + ALOGE("%s: Invalid Buffer provided. Exit", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate it randomly. + */ + requestId = get_requestid(); + + /* Set bssid blacklist */ + if (roaming_config->num_blacklist_bssid > info->capa.roaming_capa.max_blacklist_size) { + ALOGE("%s: Number of blacklist bssids(%d) provided is more than maximum blacklist bssids(%d)" + " supported", __FUNCTION__, roaming_config->num_blacklist_bssid, + info->capa.roaming_capa.max_blacklist_size); + return WIFI_ERROR_NOT_SUPPORTED; + } + bssid_params.num_bssid = roaming_config->num_blacklist_bssid; + + memcpy(bssid_params.bssids, roaming_config->blacklist_bssid, + (bssid_params.num_bssid * sizeof(mac_addr))); + + ret = wifi_set_bssid_blacklist(requestId, iface, bssid_params); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to configure blacklist bssids", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Set ssid whitelist */ + if (roaming_config->num_whitelist_ssid > info->capa.roaming_capa.max_whitelist_size) { + ALOGE("%s: Number of whitelist ssid(%d) provided is more than maximum whitelist ssids(%d) " + "supported", __FUNCTION__, roaming_config->num_whitelist_ssid, + info->capa.roaming_capa.max_whitelist_size); + return WIFI_ERROR_NOT_SUPPORTED; + } + + // Framework is always sending SSID length as 32 though null terminated lengths + // are lesser. Thus update correct lengths before sending to driver. + for (int i = 0; i < roaming_config->num_whitelist_ssid; i++) { + int j; + + for (j = 0; j < roaming_config->whitelist_ssid[i].length; j++) { + if (roaming_config->whitelist_ssid[i].ssid_str[j] == '\0') + break; + } + + if (roaming_config->whitelist_ssid[i].length == j) + continue; + + ALOGI("%s: ssid_str %s reported length = %d , null terminated length = %d", __FUNCTION__, + roaming_config->whitelist_ssid[i].ssid_str, + roaming_config->whitelist_ssid[i].length, j); + roaming_config->whitelist_ssid[i].length = j; + } + + ret = wifi_set_ssid_white_list(requestId, iface, roaming_config->num_whitelist_ssid, + roaming_config->whitelist_ssid); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Failed to configure whitelist ssids", __FUNCTION__); + + return ret; +} + +/* Enable/disable firmware roaming */ +wifi_error wifi_enable_firmware_roaming(wifi_interface_handle iface, fw_roaming_state_t state) +{ + int requestId; + wifi_error ret; + RoamCommand *roamCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + qca_roaming_policy policy; + + ALOGV("%s: set firmware roam state : %d", __FUNCTION__, state); + + if (state == ROAMING_ENABLE) { + policy = QCA_ROAMING_ALLOWED_WITHIN_ESS; + } else if(state == ROAMING_DISABLE) { + policy = QCA_ROAMING_NOT_ALLOWED; + } else { + ALOGE("%s: Invalid state provided: %d. Exit \n", __FUNCTION__, state); + return WIFI_ERROR_INVALID_ARGS; + } + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate it randomly. + */ + requestId = get_requestid(); + + roamCommand = + new RoamCommand(wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_ROAMING); + if (roamCommand == NULL) { + ALOGE("%s: Failed to create object of RoamCommand class", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = roamCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to create NL message, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = roamCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to set interface Id of message, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = roamCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + ret = roamCommand->put_u32(QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY, policy); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to add roaming policy atribute, Error: %d", __FUNCTION__, ret); + goto cleanup; + } + + roamCommand->attr_end(nlData); + + ret = roamCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Failed to send request, Error:%d", __FUNCTION__, ret); + +cleanup: + delete roamCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/roamcommand.h b/wcn6740/qcwcn/wifi_hal/roamcommand.h new file mode 100644 index 0000000..9de90b2 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/roamcommand.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_HAL_ROAM_COMMAND_H__ +#define __WIFI_HAL_ROAM_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* BSSID blacklist */ +typedef struct { + int num_bssid; // number of blacklisted BSSIDs + mac_addr bssids[MAX_BLACKLIST_BSSID]; // blacklisted BSSIDs +} wifi_bssid_params; + +class RoamCommand: public WifiVendorCommand +{ +private: + +public: + RoamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + virtual ~RoamCommand(); + + virtual wifi_error create(); + virtual wifi_error requestResponse(); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp b/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp new file mode 100644 index 0000000..832bbc3 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp @@ -0,0 +1,371 @@ +/* Copyright (c) 2015, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "rssi_monitor.h" + +/* Used to handle rssi command events from driver/firmware.*/ +typedef struct rssi_monitor_event_handler_s { + RSSIMonitorCommand* mRSSIMonitorCommandInstance; +} rssi_monitor_event_handlers; + +wifi_error initializeRSSIMonitorHandler(hal_info *info) +{ + info->rssi_handlers = (rssi_monitor_event_handlers *)malloc(sizeof( + rssi_monitor_event_handlers)); + if (info->rssi_handlers) { + memset(info->rssi_handlers, 0, sizeof(rssi_monitor_event_handlers)); + } + else { + ALOGE("%s: Allocation of RSSI event handlers failed", + __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + return WIFI_SUCCESS; +} + +wifi_error cleanupRSSIMonitorHandler(hal_info *info) +{ + rssi_monitor_event_handlers* event_handlers; + if (info && info->rssi_handlers) { + event_handlers = (rssi_monitor_event_handlers*) info->rssi_handlers; + if (event_handlers->mRSSIMonitorCommandInstance) { + delete event_handlers->mRSSIMonitorCommandInstance; + } + memset(event_handlers, 0, sizeof(rssi_monitor_event_handlers)); + free(info->rssi_handlers); + info->rssi_handlers = NULL; + return WIFI_SUCCESS; + } + ALOGE ("%s: info or info->rssi_handlers NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; +} + +void RSSIMonitorCommand::enableEventHandling() +{ + pthread_mutex_lock(&rm_lock); + mEventHandlingEnabled = true; + pthread_mutex_unlock(&rm_lock); +} + +void RSSIMonitorCommand::disableEventHandling() +{ + pthread_mutex_lock(&rm_lock); + mEventHandlingEnabled = false; + pthread_mutex_unlock(&rm_lock); +} + +bool RSSIMonitorCommand::isEventHandlingEnabled() +{ + bool eventHandlingEnabled; + pthread_mutex_lock(&rm_lock); + eventHandlingEnabled = mEventHandlingEnabled; + pthread_mutex_unlock(&rm_lock); + + return eventHandlingEnabled; +} + +void RSSIMonitorCommand::setCallbackHandler(wifi_rssi_event_handler handler) +{ + mHandler = handler; +} + +RSSIMonitorCommand::RSSIMonitorCommand(wifi_handle handle, int id, + u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mHandler, 0, sizeof(mHandler)); + if (registerVendorHandler(vendor_id, subcmd)) { + /* Error case should not happen print log */ + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", + __FUNCTION__, vendor_id, subcmd); + } + pthread_mutex_init(&rm_lock, NULL); + disableEventHandling(); +} + +RSSIMonitorCommand::~RSSIMonitorCommand() +{ + unregisterVendorHandler(mVendor_id, mSubcmd); + pthread_mutex_destroy(&rm_lock); +} + +void RSSIMonitorCommand::setReqId(wifi_request_id reqid) +{ + mId = reqid; +} + +RSSIMonitorCommand* RSSIMonitorCommand::instance(wifi_handle handle, + wifi_request_id id) +{ + if (handle == NULL) { + ALOGE("Interface Handle is invalid"); + return NULL; + } + hal_info *info = getHalInfo(handle); + if (!info || !info->rssi_handlers) { + ALOGE("rssi_handlers is invalid"); + return NULL; + } + + RSSIMonitorCommand* mRSSIMonitorCommandInstance = + info->rssi_handlers->mRSSIMonitorCommandInstance; + + if (mRSSIMonitorCommandInstance == NULL) { + mRSSIMonitorCommandInstance = new RSSIMonitorCommand(handle, id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI); + info->rssi_handlers->mRSSIMonitorCommandInstance = mRSSIMonitorCommandInstance; + return mRSSIMonitorCommandInstance; + } + else + { + if (handle != getWifiHandle(mRSSIMonitorCommandInstance->mInfo)) + { + /* upper layer must have cleaned up the handle and reinitialized, + so we need to update the same */ + ALOGV("Handle different, update the handle"); + mRSSIMonitorCommandInstance->mInfo = (hal_info *)handle; + } + mRSSIMonitorCommandInstance->setReqId(id); + } + return mRSSIMonitorCommandInstance; +} + +/* This function will be the main handler for incoming event. + * Call the appropriate callback handler after parsing the vendor data. + */ +int RSSIMonitorCommand::handleEvent(WifiEvent &event) +{ + int ret = WIFI_SUCCESS; + + if (isEventHandlingEnabled() == false) { + ALOGE("%s: RSSI monitor isn't running or already stopped. " + "Nothing to do. Exit", __FUNCTION__); + return ret; + } + + WifiVendorCommand::handleEvent(event); + + /* Parse the vendordata and get the attribute */ + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI: + { + mac_addr addr; + s8 rssi; + wifi_request_id reqId; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX + + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + memset(addr, 0, sizeof(mac_addr)); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID]) + { + ALOGE("%s: ATTR_RSSI_MONITORING_REQUEST_ID not found. Exit.", + __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + break; + } + reqId = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID] + ); + /* If event has a different request_id, ignore that and use the + * request_id value which we're maintaining. + */ + if (reqId != id()) { + ALOGV("%s: Event has Req. ID:%d <> Ours:%d, continue...", + __FUNCTION__, reqId, id()); + reqId = id(); + } + ret = get_mac_addr(tb_vendor, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, + addr); + if (ret != WIFI_SUCCESS) { + return ret; + } + ALOGV(MAC_ADDR_STR, MAC_ADDR_ARRAY(addr)); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + rssi = get_s8(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI]); + ALOGV("Current RSSI : %d ", rssi); + + if (mHandler.on_rssi_threshold_breached) + (*mHandler.on_rssi_threshold_breached)(reqId, addr, rssi); + else + ALOGE("RSSI Monitoring: No Callback registered: "); + } + break; + + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd); + } + + return ret; +} + +wifi_error wifi_start_rssi_monitoring(wifi_request_id id, + wifi_interface_handle iface, + s8 max_rssi, + s8 min_rssi, + wifi_rssi_event_handler eh) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + RSSIMonitorCommand *rssiCommand; + + ret = initialize_vendor_cmd(iface, id, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + ALOGV("%s: Max RSSI:%d Min RSSI:%d", __FUNCTION__, + max_rssi, min_rssi); + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL, + QCA_WLAN_RSSI_MONITORING_START); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_s8(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI, + max_rssi); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_s8(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI, + min_rssi); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + rssiCommand = RSSIMonitorCommand::instance(wifiHandle, id); + if (rssiCommand == NULL) { + ALOGE("%s: Error rssiCommand NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + rssiCommand->setCallbackHandler(eh); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + rssiCommand->enableEventHandling(); + +cleanup: + delete vCommand; + return ret; +} + +wifi_error wifi_stop_rssi_monitoring(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + RSSIMonitorCommand *rssiCommand; + rssi_monitor_event_handlers* event_handlers; + hal_info *info = getHalInfo(wifiHandle); + + event_handlers = info->rssi_handlers; + rssiCommand = event_handlers->mRSSIMonitorCommandInstance; + + if (rssiCommand == NULL || + rssiCommand->isEventHandlingEnabled() == false) { + ALOGE("%s: RSSI monitor isn't running or already stopped. " + "Nothing to do. Exit", __FUNCTION__); + return WIFI_ERROR_NOT_AVAILABLE; + } + + ret = initialize_vendor_cmd(iface, id, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL, + QCA_WLAN_RSSI_MONITORING_STOP); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + rssiCommand->disableEventHandling(); + +cleanup: + delete vCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/rssi_monitor.h b/wcn6740/qcwcn/wifi_hal/rssi_monitor.h new file mode 100644 index 0000000..c6ea692 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/rssi_monitor.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_RSSI_MONITOR_COMMAND_H__ +#define __WIFI_HAL_RSSI_MONITOR_COMMAND_H__ + +#include "cpp_bindings.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +class RSSIMonitorCommand: public WifiVendorCommand +{ +private: + static RSSIMonitorCommand *mRSSIMonitorCommandInstance; + wifi_rssi_event_handler mHandler; + RSSIMonitorCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + bool mEventHandlingEnabled; + /* mutex for the mEventHandlingEnabled access*/ + pthread_mutex_t rm_lock; + +public: + virtual ~RSSIMonitorCommand(); + static RSSIMonitorCommand* instance(wifi_handle handle, wifi_request_id id); + virtual int handleEvent(WifiEvent &event); + virtual void setReqId(wifi_request_id reqid); + virtual void setCallbackHandler(wifi_rssi_event_handler nHandler); + void enableEventHandling(); + void disableEventHandling(); + bool isEventHandlingEnabled(); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/rtt.cpp b/wcn6740/qcwcn/wifi_hal/rtt.cpp new file mode 100644 index 0000000..785af6d --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/rtt.cpp @@ -0,0 +1,383 @@ +/* Copyright (c) 2014, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#define LOG_TAG "WifiHAL" +#include <cutils/sched_policy.h> +#include <unistd.h> + +#include <utils/Log.h> +#include <time.h> + +#include "common.h" +#include "cpp_bindings.h" +#include "rtt.h" +#include "wifi_hal.h" +#include "wifihal_internal.h" + +/* Implementation of the API functions exposed in rtt.h */ +wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface, + wifi_rtt_capabilities *capabilities) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL) { + ALOGE("wifi_get_rtt_capabilities: NULL iface pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + if (capabilities == NULL) { + ALOGE("wifi_get_rtt_capabilities: NULL capabilities pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->get_rtt_capabilities == NULL) { + ALOGE("wifi_get_rtt_capabilities: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = (wifi_error)lowiWifiHalApi->get_rtt_capabilities(iface, capabilities); + if (ret != WIFI_SUCCESS) + ALOGE("wifi_get_rtt_capabilities: lowi_wifihal_get_rtt_capabilities " + "returned error:%d. Exit.", ret); + + return ret; +} + +/* API to request RTT measurement */ +wifi_error wifi_rtt_range_request(wifi_request_id id, + wifi_interface_handle iface, + unsigned num_rtt_config, + wifi_rtt_config rtt_config[], + wifi_rtt_event_handler handler) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + hal_info *info = NULL; + + if (iface == NULL) { + ALOGE("wifi_rtt_range_request: NULL iface pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + wifi_handle wifiHandle = getWifiHandle(iface); + info = getHalInfo(wifiHandle); + if (!info) + { + ALOGE("%s: hal_info is null ", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (!(info->supported_feature_set & WIFI_FEATURE_D2AP_RTT)) { + ALOGE("%s: RTT is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (rtt_config == NULL) { + ALOGE("wifi_rtt_range_request: NULL rtt_config pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + if (num_rtt_config <= 0) { + ALOGE("wifi_rtt_range_request: number of destination BSSIDs to " + "measure RTT on = 0. Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + if (handler.on_rtt_results == NULL) { + ALOGE("wifi_rtt_range_request: NULL capabilities pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_range_request == NULL) { + ALOGE("wifi_rtt_range_request: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = (wifi_error)lowiWifiHalApi->rtt_range_request(id, iface, + num_rtt_config, + rtt_config, handler); + if (ret != WIFI_SUCCESS) + ALOGE("wifi_rtt_range_request: lowi_wifihal_rtt_range_request " + "returned error:%d. Exit.", ret); + + return ret; +} + +/* API to cancel RTT measurements */ +wifi_error wifi_rtt_range_cancel(wifi_request_id id, + wifi_interface_handle iface, + unsigned num_devices, + mac_addr addr[]) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL) { + ALOGE("wifi_rtt_range_cancel: NULL iface pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + if (addr == NULL) { + ALOGE("wifi_rtt_range_cancel: NULL addr pointer provided." + " Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + if (num_devices <= 0) { + ALOGE("wifi_rtt_range_cancel: number of destination BSSIDs to " + "measure RTT on = 0. Exit."); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_range_cancel == NULL) { + ALOGE("wifi_rtt_range_cancel: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit."); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = (wifi_error)lowiWifiHalApi->rtt_range_cancel(id, num_devices, addr); + if (ret != WIFI_SUCCESS) + ALOGE("wifi_rtt_range_cancel: lowi_wifihal_rtt_range_cancel " + "returned error:%d. Exit.", ret); + + return ret; +} + +// API to configure the LCI. Used in RTT Responder mode only +wifi_error wifi_set_lci(wifi_request_id id, wifi_interface_handle iface, + wifi_lci_information *lci) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL) { + ALOGE("%s: NULL iface pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (lci == NULL) { + ALOGE("%s: NULL lci pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_set_lci == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = lowiWifiHalApi->rtt_set_lci(id, iface, lci); + if (ret != WIFI_SUCCESS) + ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret); + + return ret; +} + +// API to configure the LCR. Used in RTT Responder mode only. +wifi_error wifi_set_lcr(wifi_request_id id, wifi_interface_handle iface, + wifi_lcr_information *lcr) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL) { + ALOGE("%s: NULL iface pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + if (lcr == NULL) { + ALOGE("%s: NULL lcr pointer provided." + " Exit.", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + /* RTT commands are diverted through LOWI interface. */ + /* Open LOWI dynamic library, retrieve handler to LOWI APIs and initialize + * LOWI if it isn't up yet. + */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_set_lcr == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = lowiWifiHalApi->rtt_set_lcr(id, iface, lcr); + if (ret != WIFI_SUCCESS) + ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret); + + return ret; +} + +/* + * Get RTT responder information e.g. WiFi channel to enable responder on. + */ +wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface, + wifi_rtt_responder *responder_info) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL || responder_info == NULL) { + ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, + responder_info); + return WIFI_ERROR_INVALID_ARGS; + } + + /* Open LOWI dynamic library, retrieve handler to LOWI APIs */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->rtt_get_responder_info == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = lowiWifiHalApi->rtt_get_responder_info(iface, responder_info); + if (ret != WIFI_SUCCESS) + ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret); + + return ret; +} + +/** + * Enable RTT responder mode. + * channel_hint - hint of the channel information where RTT responder should + * be enabled on. + * max_duration_seconds - timeout of responder mode. + * responder_info - responder information e.g. channel used for RTT responder, + * NULL if responder is not enabled. + */ +wifi_error wifi_enable_responder(wifi_request_id id, + wifi_interface_handle iface, + wifi_channel_info channel_hint, + unsigned max_duration_seconds, + wifi_rtt_responder *responder_info) +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL || responder_info == NULL) { + ALOGE("%s: iface : %p responder_info : %p", __FUNCTION__, iface, responder_info); + return WIFI_ERROR_INVALID_ARGS; + } + + /* Open LOWI dynamic library, retrieve handler to LOWI APIs */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->enable_responder == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = lowiWifiHalApi->enable_responder(id, iface, channel_hint, + max_duration_seconds, + responder_info); + if (ret != WIFI_SUCCESS) + ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret); + + return ret; +} + + +/** + * Disable RTT responder mode. + */ +wifi_error wifi_disable_responder(wifi_request_id id, + wifi_interface_handle iface) + +{ + wifi_error ret; + lowi_cb_table_t *lowiWifiHalApi = NULL; + + if (iface == NULL) { + ALOGE("%s: iface : %p", __FUNCTION__, iface); + return WIFI_ERROR_INVALID_ARGS; + } + + /* Open LOWI dynamic library, retrieve handler to LOWI APIs */ + lowiWifiHalApi = getLowiCallbackTable( + ONE_SIDED_RANGING_SUPPORTED|DUAL_SIDED_RANGING_SUPPORED); + if (lowiWifiHalApi == NULL || + lowiWifiHalApi->disable_responder == NULL) { + ALOGE("%s: getLowiCallbackTable returned NULL or " + "the function pointer is NULL. Exit.", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = lowiWifiHalApi->disable_responder(id, iface); + if (ret != WIFI_SUCCESS) + ALOGE("%s: returned error:%d. Exit.", __FUNCTION__, ret); + + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/sync.h b/wcn6740/qcwcn/wifi_hal/sync.h new file mode 100644 index 0000000..eaa9f11 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/sync.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <pthread.h> +#include "wifi_hal.h" +#include "common.h" + +#ifndef __WIFI_HAL_SYNC_H__ +#define __WIFI_HAL_SYNC_H__ + +class Mutex +{ +private: + pthread_mutex_t mMutex; +public: + Mutex() { + pthread_mutex_init(&mMutex, NULL); + } + ~Mutex() { + pthread_mutex_destroy(&mMutex); + } + int tryLock() { + return pthread_mutex_trylock(&mMutex); + } + int lock() { + return pthread_mutex_lock(&mMutex); + } + void unlock() { + pthread_mutex_unlock(&mMutex); + } +}; + +class Condition +{ +private: + pthread_cond_t mCondition; + pthread_mutex_t mMutex; + +public: + Condition() { + pthread_mutex_init(&mMutex, NULL); + pthread_cond_init(&mCondition, NULL); + } + ~Condition() { + pthread_cond_destroy(&mCondition); + pthread_mutex_destroy(&mMutex); + } + + wifi_error wait() { + int status = pthread_cond_wait(&mCondition, &mMutex); + return mapKernelErrortoWifiHalError(status); + } + + wifi_error wait(struct timespec abstime) + { + struct timeval now; + int status; + + gettimeofday(&now,NULL); + + abstime.tv_sec += now.tv_sec; + if(((abstime.tv_nsec + now.tv_usec*1000) > 1000*1000*1000) || (abstime.tv_nsec + now.tv_usec*1000 < 0)) + { + abstime.tv_sec += 1; + abstime.tv_nsec += now.tv_usec * 1000; + abstime.tv_nsec -= 1000*1000*1000; + } + else + { + abstime.tv_nsec += now.tv_usec * 1000; + } + status = pthread_cond_timedwait(&mCondition, &mMutex, &abstime); + return mapKernelErrortoWifiHalError(status); + } + + void signal() { + pthread_cond_signal(&mCondition); + } +}; + +#endif diff --git a/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp b/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp new file mode 100644 index 0000000..c13b1b0 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp @@ -0,0 +1,364 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "vendor_definitions.h" +#include <netlink/genl/genl.h> +#include <string.h> +#include <net/if.h> +#include "tcp_params_update.h" + +TCPParamCommand::TCPParamCommand(wifi_handle handle, int id, + u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + if (registerVendorHandler(vendor_id, subcmd)) { + /* Error case should not happen print log */ + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", + __FUNCTION__, vendor_id, subcmd); + } + memset(def_tcp_limit_output_bytes, 0, SIZE_TCP_PARAM); + memset(def_tcp_adv_win_scale, 0, SIZE_TCP_PARAM); + def_tcp_limit_output_bytes_valid = false; + def_tcp_adv_win_scale_valid = false; +} + +TCPParamCommand::~TCPParamCommand() +{ + unregisterVendorHandler(OUI_QCA, QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT); +} + +TCPParamCommand *TCPParamCommand::instance(wifi_handle handle, wifi_request_id id) +{ + TCPParamCommand* mTCPParamCommandInstance; + + mTCPParamCommandInstance = new TCPParamCommand(handle, id, OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT); + return mTCPParamCommandInstance; +} + +/* This function will be the main handler for incoming event. + * Call the appropriate callback handler after parsing the vendor data. + */ +int TCPParamCommand::handleEvent(WifiEvent &event) +{ + wifi_error ret = WIFI_SUCCESS; + WifiVendorCommand::handleEvent(event); + + u8 tpDirection, tpLevel; + u32 tcpLimitOutputBytes; + u8 tcpLimitOutputBytesFlag = 0; + s8 tcpAdvWinScale; + u8 tcpAdvWinScaleFlag = 0; + u32 tcpDelackSeg; + u8 tcpDelackSegFlag = 0; + char value_to_str[100]; + int ret_val = 0; + + /* Parse the vendordata and get the attribute */ + switch(mSubcmd) { + case QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: + { + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX + 1]; + + nla_parse(tb, QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + + if (!tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION] || + !tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL]) { + ALOGE("Invalid event, didn't receive mandatory attributes"); + return WIFI_ERROR_INVALID_ARGS; + } + tpDirection = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION]); + tpLevel = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL]); + + if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES]) { + tcpLimitOutputBytes = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES]); + tcpLimitOutputBytesFlag = 1; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE]) { + tcpAdvWinScale = *(s8 *)nla_data(tb[ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE]); + tcpAdvWinScaleFlag = 1; + } + + if (tb[QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG]) { + tcpDelackSeg = nla_get_u32(tb[ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG]); + tcpDelackSegFlag = 1; + } + if (tpDirection == TP_CHANGE_RX) { + switch(tpLevel) { + case QCA_WLAN_THROUGHPUT_LEVEL_LOW: + { + if (def_tcp_adv_win_scale_valid) + wlan_service_set_tcp_adv_win_scale(def_tcp_adv_win_scale); + wlan_service_set_tcp_use_userconfig("0"); + } + break; + case QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM: + case QCA_WLAN_THROUGHPUT_LEVEL_HIGH: + { + if (tcpAdvWinScaleFlag) { + ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d", + tcpAdvWinScale); + if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) { + ALOGE("Error in converting value to string: %d", ret_val); + ret = WIFI_ERROR_UNKNOWN; + break; + } + wlan_service_set_tcp_adv_win_scale(value_to_str); + } + if (tcpDelackSegFlag && wlan_service_set_tcp_use_userconfig("1") == 0) { + ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d", + tcpDelackSeg); + if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) { + ALOGE("Error in converting value to string: %d", ret_val); + ret = WIFI_ERROR_UNKNOWN; + break; + } + wlan_service_set_tcp_delack_seg(value_to_str); + } + } + break; + default: + { + /* Error case should not happen print log */ + ALOGE("%s: Invalid throughput level value", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + } + } else if (tpDirection == TP_CHANGE_TX) { + switch(tpLevel) { + case QCA_WLAN_THROUGHPUT_LEVEL_LOW: + { + if (def_tcp_limit_output_bytes_valid) + wlan_service_set_tcp_limit_output_bytes( + def_tcp_limit_output_bytes); + } + break; + case QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM: + case QCA_WLAN_THROUGHPUT_LEVEL_HIGH: + { + if (tcpLimitOutputBytesFlag) { + ret_val = snprintf(value_to_str, sizeof(value_to_str), "%d", + tcpLimitOutputBytes); + if (ret_val < 0 || ret_val >= (int)sizeof(value_to_str)) { + ALOGE("Error in converting value to string: %d", ret_val); + ret = WIFI_ERROR_UNKNOWN; + break; + } + wlan_service_set_tcp_limit_output_bytes(value_to_str); + } + } + break; + default: + { + /* Error case should not happen print log */ + ALOGE("%s: Invalid throughput level value", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + } + } else { + /* Error case should not happen print log */ + ALOGE("%s: Invalid throughput change direction", __FUNCTION__); + return ret; + } + } + break; + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong subcmd received %d", __FUNCTION__, mSubcmd); + } + + return ret; +} + +wifi_error wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + TCPParamCommand *tcpParamCommand; + + if (wifiHandle == NULL) { + ALOGE("%s: Interface Handle is invalid", __func__); + return WIFI_ERROR_UNKNOWN; + } + + hal_info *info = getHalInfo(wifiHandle); + if (!info) + return WIFI_ERROR_UNKNOWN; + + tcpParamCommand = TCPParamCommand::instance(wifiHandle, 0); + if (tcpParamCommand == NULL) { + ALOGE("%s: Error TcpParamCommand NULL", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + info->tcp_param_handler = (tcp_param_cmd_handler *)malloc(sizeof(tcp_param_cmd_handler)); + if (info->tcp_param_handler == NULL) { + ALOGE("%s: Allocation of tcp handler failed",__FUNCTION__); + delete tcpParamCommand; + return WIFI_ERROR_OUT_OF_MEMORY; + } + info->tcp_param_handler->tcpParamCommand = tcpParamCommand; + + if (wlan_service_read_sys_param("/proc/sys/net/ipv4/tcp_limit_output_bytes", + tcpParamCommand->def_tcp_limit_output_bytes, + SIZE_TCP_PARAM) == 0) { + tcpParamCommand->def_tcp_limit_output_bytes_valid = true; + } + + if (wlan_service_read_sys_param("/proc/sys/net/ipv4/tcp_adv_win_scale", + tcpParamCommand->def_tcp_adv_win_scale, + SIZE_TCP_PARAM) == 0) { + tcpParamCommand->def_tcp_adv_win_scale_valid = true; + } + + return WIFI_SUCCESS; +} + +void cleanupTCPParamCommand(hal_info *info) { + + TCPParamCommand *tcpParamCommand; + + if (info == NULL || info->tcp_param_handler == NULL) + return; + + tcpParamCommand = info->tcp_param_handler->tcpParamCommand; + + if (tcpParamCommand) { + if (tcpParamCommand->def_tcp_limit_output_bytes_valid) + wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_limit_output_bytes", + tcpParamCommand->def_tcp_limit_output_bytes); + wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_use_userconfig", "0"); + if (tcpParamCommand->def_tcp_adv_win_scale_valid) + wlan_service_update_sys_param("/proc/sys/net/ipv4/tcp_adv_win_scale", + tcpParamCommand->def_tcp_adv_win_scale); + delete tcpParamCommand; + } + + free(info->tcp_param_handler); + + return; +} + +/** + * wlan_service_update_sys_param() + * @path: path on the file system to be modified + * @str: value to be written to the path + * + * Generic function to update a system parameter + * Return: WIFI_SUCCESS code if read is successful + * Eror code if read is failure + */ +wifi_error wlan_service_update_sys_param(const char *path, const char *str) +{ + int ret; + FILE *fp; + fp = fopen(path, "w"); + + if (fp == NULL) { + ALOGE("%s: unable to open %s", __FUNCTION__, path); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: %s %s", __FUNCTION__, path, str); + + ret = fputs(str, fp); + fclose(fp); + + if (ret < 0) { + ALOGE("%s: failed to write %s to %s with err %d", __FUNCTION__, str, path, ret); + return mapKernelErrortoWifiHalError(ret); + } + + return WIFI_SUCCESS; +} + +/** + * wlan_service_read_sys_param() + * @path: path on the file system to be read + * @str: value read from the path + * + * Generic function to read a system parameter + * Return: WIFI_SUCCESS code if read is successful + * Eror code if read is failure + */ +wifi_error wlan_service_read_sys_param(const char *path, char *str, size_t max_size) +{ + size_t ret_len; + FILE *fp = fopen(path, "r"); + + if (fp == NULL) { + ALOGE("%s: unable to open %s", __FUNCTION__, path); + return WIFI_ERROR_UNKNOWN; + } + + ret_len = fread(str, 1, max_size, fp); + fclose(fp); + + if (ret_len == 0 || ret_len == max_size) { + ALOGE("Faild to read %s, ret_len = %zu", path, ret_len); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: %s %s", __FUNCTION__, path, str); + return WIFI_SUCCESS; +} + +int TCPParamCommand::wlan_service_set_tcp_adv_win_scale(char *str) +{ + return wlan_service_update_sys_param( + "/proc/sys/net/ipv4/tcp_adv_win_scale", str); +} + +int TCPParamCommand::wlan_service_set_tcp_use_userconfig(const char *str) +{ + return wlan_service_update_sys_param( + "/proc/sys/net/ipv4/tcp_use_userconfig", str); +} + +int TCPParamCommand::wlan_service_set_tcp_delack_seg(char *str) +{ + return wlan_service_update_sys_param( + "/proc/sys/net/ipv4/tcp_delack_seg", str); +} + +int TCPParamCommand::wlan_service_set_tcp_limit_output_bytes(char *str) +{ + return wlan_service_update_sys_param ( + "/proc/sys/net/ipv4/tcp_limit_output_bytes", str); +} diff --git a/wcn6740/qcwcn/wifi_hal/tcp_params_update.h b/wcn6740/qcwcn/wifi_hal/tcp_params_update.h new file mode 100644 index 0000000..184372d --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/tcp_params_update.h @@ -0,0 +1,81 @@ +/* Copyright (c) 2018-2019, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_TCP_PARAM_UPDATE_COMMAND_H__ +#define __WIFI_HAL_TCP_PARAM_UPDATE_COMMAND_H__ + +#include "cpp_bindings.h" +#include "common.h" +#include <errno.h> + +#define SIZE_TCP_PARAM 100 +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +/* Indicates the direction of throughput in which the change is being + * reported. u8 attribute. Value is 0 for TX and 1 for RX. + */ +typedef enum { + TP_CHANGE_TX = 0, + TP_CHANGE_RX = 1 +} TpChangeDirection; + +wifi_error wlan_service_update_sys_param(const char *path, const char *str); +wifi_error wlan_service_read_sys_param(const char *path, char *str, size_t max_size); +void cleanupTCPParamCommand(hal_info *info); + +class TCPParamCommand: public WifiVendorCommand +{ +private: + TCPParamCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + int wlan_service_set_tcp_adv_win_scale(char *str); + int wlan_service_set_tcp_use_userconfig(const char *str); + int wlan_service_set_tcp_delack_seg(char *str); + int wlan_service_set_tcp_limit_output_bytes(char *str); + +public: + virtual ~TCPParamCommand(); + static TCPParamCommand *instance(wifi_handle handle, + wifi_request_id id); + virtual int handleEvent(WifiEvent &event); + char def_tcp_limit_output_bytes[SIZE_TCP_PARAM]; + bool def_tcp_limit_output_bytes_valid; + char def_tcp_adv_win_scale[SIZE_TCP_PARAM]; + bool def_tcp_adv_win_scale_valid; +}; + +/* Used to clean TCPParam object*/ +typedef struct tcp_param_cmd_handler_s { + TCPParamCommand *tcpParamCommand; +} tcp_param_cmd_handler; +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/tdls.cpp b/wcn6740/qcwcn/wifi_hal/tdls.cpp new file mode 100644 index 0000000..f12816f --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/tdls.cpp @@ -0,0 +1,572 @@ +/* Copyright (c) 2014, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "tdlsCommand.h" +#include "vendor_definitions.h" + +/* Singleton Static Instance */ +TdlsCommand* TdlsCommand::mTdlsCommandInstance = NULL; +TdlsCommand::TdlsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mHandler, 0, sizeof(mHandler)); + memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status)); + mRequestId = 0; +} + +TdlsCommand::~TdlsCommand() +{ + mTdlsCommandInstance = NULL; + unregisterVendorHandler(mVendor_id, mSubcmd); +} + +TdlsCommand* TdlsCommand::instance(wifi_handle handle) +{ + if (handle == NULL) { + ALOGE("Interface Handle is invalid"); + return NULL; + } + if (mTdlsCommandInstance == NULL) { + mTdlsCommandInstance = new TdlsCommand(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE); + ALOGV("TdlsCommand %p created", mTdlsCommandInstance); + return mTdlsCommandInstance; + } + else + { + if (handle != getWifiHandle(mTdlsCommandInstance->mInfo)) + { + /* upper layer must have cleaned up the handle and reinitialized, + so we need to update the same */ + ALOGV("Handle different, update the handle"); + mTdlsCommandInstance->mInfo = (hal_info *)handle; + } + } + ALOGV("TdlsCommand %p created already", mTdlsCommandInstance); + return mTdlsCommandInstance; +} + +void TdlsCommand::setSubCmd(u32 subcmd) +{ + mSubcmd = subcmd; +} + +/* This function will be the main handler for incoming event SUBCMD_TDLS + * Call the appropriate callback handler after parsing the vendor data. + */ +int TdlsCommand::handleEvent(WifiEvent &event) +{ + ALOGV("Got a TDLS message from Driver"); + WifiVendorCommand::handleEvent(event); + + /* Parse the vendordata and get the attribute */ + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE: + { + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX + + 1]; + mac_addr addr; + wifi_tdls_status status; + + memset(&addr, 0, sizeof(mac_addr)); + memset(&status, 0, sizeof(wifi_tdls_status)); + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE Received"); + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + memcpy(addr, + (u8 *)nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR]), + nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_MAC_ADDR])); + + ALOGV(MAC_ADDR_STR, MAC_ADDR_ARRAY(addr)); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_STATE not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + status.state = (wifi_tdls_state) + get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_STATE]); + ALOGV("TDLS: State New : %d ", status.state); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_REASON not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + status.reason = (wifi_tdls_reason) + get_s32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_REASON]); + ALOGV("TDLS: Reason : %d ", status.reason); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL not found", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + status.channel = + get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL]); + ALOGV("TDLS: channel : %d ", status.channel); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + status.global_operating_class = get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS]); + ALOGV("TDLS: global_operating_class: %d ", + status.global_operating_class); + + if (mHandler.on_tdls_state_changed) + (*mHandler.on_tdls_state_changed)(addr, status); + else + ALOGE("TDLS: No Callback registered: "); + } + break; + + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong TDLS subcmd received %d", __FUNCTION__, mSubcmd); + } + + return NL_SKIP; +} + +int TdlsCommand::handleResponse(WifiEvent &reply) +{ + WifiVendorCommand::handleResponse(reply); + + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS: + { + struct nlattr *tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + ALOGV("QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS Received"); + memset(&mTDLSgetStatusRspParams, 0, sizeof(wifi_tdls_status)); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetStatusRspParams.state = (wifi_tdls_state)get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE]); + ALOGV("TDLS: State : %u ", mTDLSgetStatusRspParams.state); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetStatusRspParams.reason = (wifi_tdls_reason)get_s32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON]); + ALOGV("TDLS: Reason : %d ", mTDLSgetStatusRspParams.reason); + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetStatusRspParams.channel = get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL]); + ALOGV("TDLS: channel : %d ", mTDLSgetStatusRspParams.channel); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]) + { + ALOGE("%s:" + "QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS" + " not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetStatusRspParams.global_operating_class = + get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]); + ALOGV("TDLS: global_operating_class: %d ", + mTDLSgetStatusRspParams.global_operating_class); + } + break; + case QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES: + { + struct nlattr *tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX + 1]; + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + memset(&mTDLSgetCaps, 0, sizeof(wifiTdlsCapabilities)); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS] + ) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_" + "MAX_CONC_SESSIONS not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetCaps.maxConcurrentTdlsSessionNum = get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS]); + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED]) + { + ALOGE("%s: QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_" + "FEATURES_SUPPORTED not found", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + mTDLSgetCaps.tdlsSupportedFeatures = get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED]); + } + break; + default : + ALOGE("%s: Wrong TDLS subcmd response received %d", + __FUNCTION__, mSubcmd); + } + return NL_SKIP; +} + + +wifi_error TdlsCommand::setCallbackHandler(wifi_tdls_handler nHandler, u32 event) +{ + wifi_error res; + mHandler = nHandler; + + res = registerVendorHandler(mVendor_id, event); + if (res != WIFI_SUCCESS) { + /* Error case should not happen print log */ + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", + __FUNCTION__, mVendor_id, mSubcmd); + } + return res; +} + +void TdlsCommand::unregisterHandler(u32 subCmd) +{ + unregisterVendorHandler(mVendor_id, subCmd); +} + +void TdlsCommand::getStatusRspParams(wifi_tdls_status *status) +{ + status->channel = mTDLSgetStatusRspParams.channel; + status->global_operating_class = + mTDLSgetStatusRspParams.global_operating_class; + status->state = mTDLSgetStatusRspParams.state; + status->reason = mTDLSgetStatusRspParams.reason; +} + +wifi_error TdlsCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +void TdlsCommand::getCapsRspParams(wifi_tdls_capabilities *caps) +{ + caps->max_concurrent_tdls_session_num = + mTDLSgetCaps.maxConcurrentTdlsSessionNum; + caps->is_global_tdls_supported = + !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_GLOBAL_TDLS_SUPPORTED); + caps->is_per_mac_tdls_supported = + !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_PER_MAC_TDLS_SUPPORTED); + caps->is_off_channel_tdls_supported = + !!(mTDLSgetCaps.tdlsSupportedFeatures & IS_OFF_CHANNEL_TDLS_SUPPORTED); + ALOGV("TDLS capabilities:"); + ALOGV("max_concurrent_tdls_session_numChannel : %d\n", + caps->max_concurrent_tdls_session_num); + ALOGV("is_global_tdls_supported : %d\n", + caps->is_global_tdls_supported); + ALOGV("is_per_mac_tdls_supported : %d\n", + caps->is_per_mac_tdls_supported); + ALOGV("is_off_channel_tdls_supported : %d \n", + caps->is_off_channel_tdls_supported); +} + +/* wifi_enable_tdls - enables TDLS-auto mode for a specific route + * + * params specifies hints, which provide more information about + * why TDLS is being sought. The firmware should do its best to + * honor the hints before downgrading regular AP link + * + * On successful completion, must fire on_tdls_state_changed event + * to indicate the status of TDLS operation. + */ +wifi_error wifi_enable_tdls(wifi_interface_handle iface, + mac_addr addr, + wifi_tdls_params *params, + wifi_tdls_handler handler) +{ + wifi_error ret; + TdlsCommand *pTdlsCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + pTdlsCommand = TdlsCommand::instance(handle); + + if (pTdlsCommand == NULL) { + ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE); + + /* Create the message */ + ret = pTdlsCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the attributes */ + nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr)); + ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR, + (char *)addr, 6); + if (ret != WIFI_SUCCESS) + goto cleanup; + + if (params != NULL) { + ALOGV("%s: Channel: %d, Global operating class: %d, " + "Max Latency: %dms, Min Bandwidth: %dKbps", + __FUNCTION__, params->channel, params->global_operating_class, + params->max_latency_ms, params->min_bandwidth_kbps); + ret = pTdlsCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL, + params->channel); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = pTdlsCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS, + params->global_operating_class); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = pTdlsCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS, + params->max_latency_ms); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = pTdlsCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS, + params->min_bandwidth_kbps); + if (ret != WIFI_SUCCESS) + goto cleanup; + } + + pTdlsCommand->attr_end(nl_data); + + ret = pTdlsCommand->setCallbackHandler(handler, + QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + +cleanup: + return ret; +} + +/* wifi_disable_tdls - disables TDLS-auto mode for a specific route + * + * This terminates any existing TDLS with addr device, and frees the + * device resources to make TDLS connections on new routes. + * + * DON'T fire any more events on 'handler' specified in earlier call to + * wifi_enable_tdls after this action. + */ +wifi_error wifi_disable_tdls(wifi_interface_handle iface, mac_addr addr) +{ + wifi_error ret; + TdlsCommand *pTdlsCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + pTdlsCommand = TdlsCommand::instance(handle); + + if (pTdlsCommand == NULL) { + ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE); + + /* Create the message */ + ret = pTdlsCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret); + ALOGV("%s: MAC_ADDR: " MAC_ADDR_STR, __FUNCTION__, MAC_ADDR_ARRAY(addr)); + + /* Add the attributes */ + nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR, + (char *)addr, 6); + if (ret != WIFI_SUCCESS) + goto cleanup; + pTdlsCommand->attr_end(nl_data); + + ret = pTdlsCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + +cleanup: + delete pTdlsCommand; + return ret; +} + +/* wifi_get_tdls_status - allows getting the status of TDLS for a specific + * route + */ +wifi_error wifi_get_tdls_status(wifi_interface_handle iface, mac_addr addr, + wifi_tdls_status *status) +{ + wifi_error ret; + TdlsCommand *pTdlsCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + pTdlsCommand = TdlsCommand::instance(handle); + + if (pTdlsCommand == NULL) { + ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS); + + /* Create the message */ + ret = pTdlsCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + ALOGV("%s: ifindex obtained:%d", __FUNCTION__, ret); + + /* Add the attributes */ + nl_data = pTdlsCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + ret = pTdlsCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR, + (char *)addr, 6); + if (ret != WIFI_SUCCESS) + goto cleanup; + pTdlsCommand->attr_end(nl_data); + + ret = pTdlsCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + + pTdlsCommand->getStatusRspParams(status); + +cleanup: + return ret; +} + +/* return the current HW + Firmware combination's TDLS capabilities */ +wifi_error wifi_get_tdls_capabilities(wifi_interface_handle iface, + wifi_tdls_capabilities *capabilities) +{ + wifi_error ret; + TdlsCommand *pTdlsCommand; + + if (capabilities == NULL) { + ALOGE("%s: capabilities is NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + pTdlsCommand = TdlsCommand::instance(handle); + + if (pTdlsCommand == NULL) { + ALOGE("%s: Error TdlsCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + pTdlsCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES); + + /* Create the message */ + ret = pTdlsCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = pTdlsCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + goto cleanup; + } + pTdlsCommand->getCapsRspParams(capabilities); + +cleanup: + if (ret != WIFI_SUCCESS) + memset(capabilities, 0, sizeof(wifi_tdls_capabilities)); + delete pTdlsCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/tdlsCommand.h b/wcn6740/qcwcn/wifi_hal/tdlsCommand.h new file mode 100644 index 0000000..565e9b3 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/tdlsCommand.h @@ -0,0 +1,111 @@ +/* Copyright (c) 2014, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_LLSTATSCOMMAND_H__ +#define __WIFI_HAL_LLSTATSCOMMAND_H__ + +#include <stdint.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> + +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <net/if.h> + +#include "nl80211_copy.h" +#include "common.h" +#include "cpp_bindings.h" +#include "tdls.h" + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define IS_GLOBAL_TDLS_SUPPORTED BIT(0) +#define IS_PER_MAC_TDLS_SUPPORTED BIT(1) +#define IS_OFF_CHANNEL_TDLS_SUPPORTED BIT(2) + +typedef struct { + int maxConcurrentTdlsSessionNum; + u32 tdlsSupportedFeatures; +} wifiTdlsCapabilities; + +class TdlsCommand: public WifiVendorCommand +{ +private: + static TdlsCommand *mTdlsCommandInstance; + wifi_tdls_status mTDLSgetStatusRspParams; + wifi_request_id mRequestId; + wifi_tdls_handler mHandler; + wifiTdlsCapabilities mTDLSgetCaps; + + TdlsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + +public: + static TdlsCommand* instance(wifi_handle handle); + virtual ~TdlsCommand(); + + virtual void setSubCmd(u32 subcmd); + + virtual wifi_error requestResponse(); + + virtual int handleEvent(WifiEvent &event); + + virtual int handleResponse(WifiEvent &reply); + + virtual wifi_error setCallbackHandler(wifi_tdls_handler nHandler, u32 event); + + virtual void unregisterHandler(u32 subCmd); + + virtual void getStatusRspParams(wifi_tdls_status *status); + + virtual void getCapsRspParams(wifi_tdls_capabilities *caps); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/vendor_definitions.h b/wcn6740/qcwcn/wifi_hal/vendor_definitions.h new file mode 100644 index 0000000..d542148 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/vendor_definitions.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VENDOR_DEFINITIONS_H__ +#define __VENDOR_DEFINITIONS_H__ + +#include "qca-vendor_copy.h" + +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, + 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, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS, + /* 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_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_TDLS_STATE, + QCA_WLAN_VENDOR_ATTR_TDLS_REASON, + QCA_WLAN_VENDOR_ATTR_TDLS_CHANNEL, + QCA_WLAN_VENDOR_ATTR_TDLS_GLOBAL_OPERATING_CLASS, + /* 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_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, +}; + +/* These are not used currently but we might need these in future */ +enum qca_wlan_epno_type +{ + QCA_WLAN_EPNO, + QCA_WLAN_PNO +}; + +enum qca_wlan_vendor_attr_ndp_cfg_security +{ + /* Security info will be added when proposed in the specification */ + QCA_WLAN_VENDOR_ATTR_NDP_SECURITY_TYPE = 1, + +}; +#endif diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp new file mode 100644 index 0000000..e43b770 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifi_hal.cpp @@ -0,0 +1,3433 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include <stdint.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netpacket/packet.h> +#include <linux/filter.h> +#include <linux/errqueue.h> +#include <linux-private/linux/fib_rules.h> +#include <linux/pkt_sched.h> +#include <netlink/object-api.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> +#include <netlink-private/object-api.h> +#include <netlink-private/types.h> + +#include "nl80211_copy.h" + +#include <dirent.h> +#include <net/if.h> +#include <netinet/in.h> +#include <cld80211_lib.h> + +#include <sys/types.h> +#include "list.h" +#include <unistd.h> + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include "wifi_hal.h" +#include "wifi_hal_ctrl.h" +#include "common.h" +#include "cpp_bindings.h" +#include "ifaceeventhandler.h" +#include "wifiloggercmd.h" +#include "tcp_params_update.h" + +/* + BUGBUG: normally, libnl allocates ports for all connections it makes; but + being a static library, it doesn't really know how many other netlink + connections are made by the same process, if connections come from different + shared libraries. These port assignments exist to solve that + problem - temporarily. We need to fix libnl to try and allocate ports across + the entire process. + */ + +#define WIFI_HAL_CMD_SOCK_PORT 644 +#define WIFI_HAL_EVENT_SOCK_PORT 645 + +#define MAX_HW_VER_LENGTH 100 +/* + * Defines for wifi_wait_for_driver_ready() + * Specify durations between polls and max wait time + */ +#define POLL_DRIVER_DURATION_US (100000) +#define POLL_DRIVER_MAX_TIME_MS (10000) + +static int attach_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg); + +static int dettach_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg); + +static int register_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg, int attach); + +static int send_nl_data(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg); + +static int internal_pollin_handler(wifi_handle handle, struct nl_sock *sock); + +static void internal_event_handler_app(wifi_handle handle, int events, + struct ctrl_sock *sock); + +static void internal_event_handler(wifi_handle handle, int events, + struct nl_sock *sock); +static int internal_valid_message_handler(nl_msg *msg, void *arg); +static int user_sock_message_handler(nl_msg *msg, void *arg); +static int wifi_get_multicast_id(wifi_handle handle, const char *name, + const char *group); +static int wifi_add_membership(wifi_handle handle, const char *group); +static wifi_error wifi_init_interfaces(wifi_handle handle); +static wifi_error wifi_set_packet_filter(wifi_interface_handle iface, + const u8 *program, u32 len); +static wifi_error wifi_get_packet_filter_capabilities(wifi_interface_handle handle, + u32 *version, u32 *max_len); +static wifi_error wifi_read_packet_filter(wifi_interface_handle handle, + u32 src_offset, u8 *host_dst, u32 length); +static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, + u8 enable); +wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface, + WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt); +static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle handle); + +wifi_error + wifi_init_tcp_param_change_event_handler(wifi_interface_handle iface); + +wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, + u32 iface_mode_mask, u32 filter_mask, + u32 max_size, u32* size, + wifi_usable_channel* channels); + +/* Initialize/Cleanup */ + +wifi_interface_handle wifi_get_iface_handle(wifi_handle handle, char *name) +{ + hal_info *info = (hal_info *)handle; + for (int i=0;i<info->num_interfaces;i++) + { + if (!strcmp(info->interfaces[i]->name, name)) + { + return ((wifi_interface_handle )(info->interfaces)[i]); + } + } + return NULL; +} + +void wifi_socket_set_local_port(struct nl_sock *sock, uint32_t port) +{ + /* Release local port pool maintained by libnl and assign a own port + * identifier to the socket. + */ + nl_socket_set_local_port(sock, ((uint32_t)getpid() & 0x3FFFFFU) | (port << 22)); +} + +static nl_sock * wifi_create_nl_socket(int port, int protocol) +{ + // ALOGI("Creating socket"); + struct nl_sock *sock = nl_socket_alloc(); + if (sock == NULL) { + ALOGE("Failed to create NL socket"); + return NULL; + } + + wifi_socket_set_local_port(sock, port); + + if (nl_connect(sock, protocol)) { + ALOGE("Could not connect handle"); + nl_socket_free(sock); + return NULL; + } + + return sock; +} + +void wifi_create_ctrl_socket(hal_info *info) +{ +#ifdef ANDROID + struct group *grp_wifi; + gid_t gid_wifi; + struct passwd *pwd_system; + uid_t uid_system; +#endif + + int flags; + + info->wifihal_ctrl_sock.s = socket(PF_UNIX, SOCK_DGRAM, 0); + + if (info->wifihal_ctrl_sock.s < 0) { + ALOGE("socket(PF_UNIX): %s", strerror(errno)); + return; + } + memset(&info->wifihal_ctrl_sock.local, 0, sizeof(info->wifihal_ctrl_sock.local)); + + info->wifihal_ctrl_sock.local.sun_family = AF_UNIX; + + snprintf(info->wifihal_ctrl_sock.local.sun_path, + sizeof(info->wifihal_ctrl_sock.local.sun_path), "%s", WIFI_HAL_CTRL_IFACE); + + if (bind(info->wifihal_ctrl_sock.s, (struct sockaddr *) &info->wifihal_ctrl_sock.local, + sizeof(info->wifihal_ctrl_sock.local)) < 0) { + ALOGD("ctrl_iface bind(PF_UNIX) failed: %s", + strerror(errno)); + if (connect(info->wifihal_ctrl_sock.s, (struct sockaddr *) &info->wifihal_ctrl_sock.local, + sizeof(info->wifihal_ctrl_sock.local)) < 0) { + ALOGD("ctrl_iface exists, but does not" + " allow connections - assuming it was left" + "over from forced program termination"); + if (unlink(info->wifihal_ctrl_sock.local.sun_path) < 0) { + ALOGE("Could not unlink existing ctrl_iface socket '%s': %s", + info->wifihal_ctrl_sock.local.sun_path, strerror(errno)); + goto out; + + } + if (bind(info->wifihal_ctrl_sock.s , + (struct sockaddr *) &info->wifihal_ctrl_sock.local, + sizeof(info->wifihal_ctrl_sock.local)) < 0) { + ALOGE("wifihal-ctrl-iface-init: bind(PF_UNIX): %s", + strerror(errno)); + goto out; + } + ALOGD("Successfully replaced leftover " + "ctrl_iface socket '%s'", info->wifihal_ctrl_sock.local.sun_path); + } else { + ALOGI("ctrl_iface exists and seems to " + "be in use - cannot override it"); + ALOGI("Delete '%s' manually if it is " + "not used anymore", info->wifihal_ctrl_sock.local.sun_path); + goto out; + } + } + + /* + * Make socket non-blocking so that we don't hang forever if + * target dies unexpectedly. + */ + +#ifdef ANDROID + if (chmod(info->wifihal_ctrl_sock.local.sun_path, S_IRWXU | S_IRWXG) < 0) + { + ALOGE("Failed to give permissions: %s", strerror(errno)); + } + + /* Set group even if we do not have privileges to change owner */ + grp_wifi = getgrnam("wifi"); + gid_wifi = grp_wifi ? grp_wifi->gr_gid : 0; + pwd_system = getpwnam("system"); + uid_system = pwd_system ? pwd_system->pw_uid : 0; + if (!gid_wifi || !uid_system) { + ALOGE("Failed to get grp ids"); + unlink(info->wifihal_ctrl_sock.local.sun_path); + goto out; + } + chown(info->wifihal_ctrl_sock.local.sun_path, -1, gid_wifi); + chown(info->wifihal_ctrl_sock.local.sun_path, uid_system, gid_wifi); +#endif + + flags = fcntl(info->wifihal_ctrl_sock.s, F_GETFL); + if (flags >= 0) { + flags |= O_NONBLOCK; + if (fcntl(info->wifihal_ctrl_sock.s, F_SETFL, flags) < 0) { + ALOGI("fcntl(ctrl, O_NONBLOCK): %s", + strerror(errno)); + /* Not fatal, continue on.*/ + } + } + return; + +out: + close(info->wifihal_ctrl_sock.s); + info->wifihal_ctrl_sock.s = 0; + return; +} + +int ack_handler(struct nl_msg *msg, void *arg) +{ + int *err = (int *)arg; + *err = 0; + return NL_STOP; +} + +int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + *ret = 0; + return NL_SKIP; +} + +int error_handler(struct sockaddr_nl *nla, + struct nlmsgerr *err, void *arg) +{ + int *ret = (int *)arg; + *ret = err->error; + + ALOGV("%s invoked with error: %d", __func__, err->error); + return NL_SKIP; +} +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} + +static wifi_error acquire_supported_features(wifi_interface_handle iface, + feature_set *set) +{ + wifi_error ret; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + *set = 0; + + WifihalGeneric supportedFeatures(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES); + + /* create the message */ + ret = supportedFeatures.create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = supportedFeatures.set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = supportedFeatures.requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__func__, ret); + goto cleanup; + } + + supportedFeatures.getResponseparams(set); + +cleanup: + return ret; +} + +static wifi_error acquire_driver_supported_features(wifi_interface_handle iface, + features_info *driver_features) +{ + wifi_error ret; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + + WifihalGeneric driverFeatures(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES); + + /* create the message */ + ret = driverFeatures.create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = driverFeatures.set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = driverFeatures.requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__func__, ret); + goto cleanup; + } + + driverFeatures.getDriverFeatures(driver_features); + +cleanup: + return mapKernelErrortoWifiHalError(ret); +} + +static wifi_error wifi_get_capabilities(wifi_interface_handle handle) +{ + wifi_error ret; + int requestId; + WifihalGeneric *wifihalGeneric; + wifi_handle wifiHandle = getWifiHandle(handle); + hal_info *info = getHalInfo(wifiHandle); + + if (!(info->supported_feature_set & WIFI_FEATURE_GSCAN)) { + ALOGE("%s: GSCAN is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate it randomly. + */ + requestId = get_requestid(); + + wifihalGeneric = new WifihalGeneric( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES); + if (!wifihalGeneric) { + ALOGE("%s: Failed to create object of WifihalGeneric class", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + ret = wifihalGeneric->wifiGetCapabilities(handle); + + delete wifihalGeneric; + return ret; +} + +static wifi_error get_firmware_bus_max_size_supported( + wifi_interface_handle iface) +{ + wifi_error ret; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + hal_info *info = (hal_info *)handle; + + WifihalGeneric busSizeSupported(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE); + + /* create the message */ + ret = busSizeSupported.create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = busSizeSupported.set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = busSizeSupported.requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + goto cleanup; + } + info->firmware_bus_max_size = busSizeSupported.getBusSize(); + +cleanup: + return ret; +} + +static wifi_error wifi_init_user_sock(hal_info *info) +{ + struct nl_sock *user_sock = + wifi_create_nl_socket(WIFI_HAL_USER_SOCK_PORT, NETLINK_USERSOCK); + if (user_sock == NULL) { + ALOGE("Could not create diag sock"); + return WIFI_ERROR_UNKNOWN; + } + + /* Set the socket buffer size */ + if (nl_socket_set_buffer_size(user_sock, (256*1024), 0) < 0) { + ALOGE("Could not set size for user_sock: %s", + strerror(errno)); + /* continue anyway with the default (smaller) buffer */ + } + else { + ALOGV("nl_socket_set_buffer_size successful for user_sock"); + } + + struct nl_cb *cb = nl_socket_get_cb(user_sock); + if (cb == NULL) { + ALOGE("Could not get cb"); + return WIFI_ERROR_UNKNOWN; + } + + info->user_sock_arg = 1; + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->user_sock_arg); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->user_sock_arg); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->user_sock_arg); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, user_sock_message_handler, info); + nl_cb_put(cb); + + int ret = nl_socket_add_membership(user_sock, 1); + if (ret < 0) { + ALOGE("Could not add membership"); + return WIFI_ERROR_UNKNOWN; + } + + info->user_sock = user_sock; + ALOGV("Initiialized diag sock successfully"); + return WIFI_SUCCESS; +} + +static wifi_error wifi_init_cld80211_sock_cb(hal_info *info) +{ + struct nl_cb *cb = nl_socket_get_cb(info->cldctx->sock); + if (cb == NULL) { + ALOGE("Could not get cb"); + return WIFI_ERROR_UNKNOWN; + } + + info->user_sock_arg = 1; + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->user_sock_arg); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->user_sock_arg); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->user_sock_arg); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, user_sock_message_handler, info); + nl_cb_put(cb); + + return WIFI_SUCCESS; +} + +static uint32_t get_frequency_from_channel(uint32_t channel, wlan_mac_band band) +{ + uint32_t freq = 0; + + switch (band) + { + case WLAN_MAC_2_4_BAND: + if (!(channel >= 1 && channel <= 14)) + goto failure; + //special handling for channel 14 by filling freq here + if (channel == 14) + freq = 2484; + else + freq = 2407 + (channel * 5); + break; + case WLAN_MAC_5_0_BAND: + if (!((channel >= 34 && channel < 65) || + (channel > 99 && channel <= 196))) + goto failure; + freq = 5000 + (channel * 5); + break; + case WLAN_MAC_6_0_BAND: + if (!(channel >= 1 && channel <= 233)) + goto failure; + freq = 5950 + (channel * 5); + break; + default: + break; + } + +failure: + return freq; +} + +static u32 get_nl_ifmask_from_coex_restriction_mask(u32 in_mask) +{ + u32 op_mask = 0; + + if (!in_mask) + return op_mask; + if (in_mask & SOFTAP) + op_mask |= BIT(NL80211_IFTYPE_AP); + if (in_mask & WIFI_DIRECT) + op_mask |= BIT(NL80211_IFTYPE_P2P_GO); + if (in_mask & WIFI_AWARE) + op_mask |= BIT(NL80211_IFTYPE_NAN); + + return op_mask; +} + +wifi_error wifi_set_coex_unsafe_channels(wifi_handle handle, u32 num_channels, + wifi_coex_unsafe_channel *unsafeChannels, + u32 restrictions) +{ + wifi_error ret = WIFI_ERROR_UNKNOWN; + WifihalGeneric *cmd = NULL; + struct nlattr *nl_data = NULL; + struct nlattr *nl_attr_unsafe_chan = NULL; + struct nlattr *unsafe_channels_attr = NULL; + hal_info *info = NULL; + + if (!handle) { + ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__); + goto cleanup; + } + + info = getHalInfo(handle); + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present", + __FUNCTION__); + goto cleanup; + } + + cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT); + if (cmd == NULL) { + ALOGE("%s: Error, created command NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + /* Create the NL message. */ + ret = cmd->create(); + if (ret < 0) { + ALOGE("%s: failed to create NL msg due to error: (%d)", + __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + ALOGE("%s: failed attr_start for NL80211_ATTR_VENDOR_DATA", + __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + nl_attr_unsafe_chan = cmd->attr_start( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE); + if (!nl_attr_unsafe_chan) { + ALOGE("%s: failed attr_start for" + " QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + ALOGD("%s: num_channels:%d, restrictions:%x", __FUNCTION__, num_channels, + restrictions); + if (num_channels == 0) { + unsafe_channels_attr = cmd->attr_start(0); + if (!unsafe_channels_attr) { + ALOGE("%s: failed attr_start for unsafe_channels_attr when" + " trying to clear usafe channels clear", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + ret = cmd->put_u32( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, 0); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put frequency start, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + ret = cmd->put_u32( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, 0); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put frequency end, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + cmd->attr_end(unsafe_channels_attr); + } + else { + if (!unsafeChannels) { + ALOGE("%s: unsafe channels buffer should not be NULL when" + " there are unsafe channels", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + } + for (int i = 0; i < num_channels; i++) { + unsafe_channels_attr = cmd->attr_start(i); + if (!unsafe_channels_attr) { + ALOGE("%s: failed attr_start for unsafe_channels_attr of" + " index:%d", __FUNCTION__, i); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + u32 freq = get_frequency_from_channel(unsafeChannels[i].channel, + unsafeChannels[i].band); + if (!freq) { + ALOGE("%s: Failed to get frequency of band:%d, channel:%d", + __FUNCTION__, (int)unsafeChannels[i].band, + unsafeChannels[i].channel); + ret = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + ret = cmd->put_u32( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, freq); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put frequency start, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + ret = cmd->put_u32( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, freq); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put frequency end, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + /** + * WIFI_COEX_NO_POWER_CAP (0x7FFFFFF) is specific to android + * framework, this value denotes that framework/wifihal is not + * providing any power cap and allow driver/firmware to operate on + * current power cap dbm. As driver is supposed to work on with + * LA/LE etc, we are skipping to send 0x7FFFFFF down to driver, + * hence driver will be operating as per current power cap calculated + * based on regulatory or other constraints. + */ + if (unsafeChannels[i].power_cap_dbm != WIFI_COEX_NO_POWER_CAP) { + ret = cmd->put_s32( + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM, + unsafeChannels[i].power_cap_dbm); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put power_cap_dbm, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + } + cmd->attr_end(unsafe_channels_attr); + ALOGD("%s: channel:%d, freq:%d, power_cap_dbm:%d, band:%d", + __FUNCTION__, unsafeChannels[i].channel, freq, + unsafeChannels[i].power_cap_dbm, unsafeChannels[i].band); + } + cmd->attr_end(nl_attr_unsafe_chan); + if (num_channels > 0) { + ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK, + get_nl_ifmask_from_coex_restriction_mask(restrictions)); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to put restrictions mask, ret:%d", + __FUNCTION__, ret); + goto cleanup; + } + } + cmd->attr_end(nl_data); + + /* Send the msg and wait for a response. */ + ret = cmd->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + if (cmd) + delete cmd; + return ret; +} + +wifi_error wifi_set_dtim_config(wifi_interface_handle handle, u32 multiplier) +{ + wifi_error ret = WIFI_ERROR_INVALID_ARGS; + WifihalGeneric *cmd = NULL; + struct nlattr *nlData = NULL; + interface_info *ifaceInfo = NULL; + wifi_handle wifiHandle = NULL; + + if (!handle) { + ALOGE("%s: Error, wifi_interface_handle NULL", __FUNCTION__); + goto cleanup; + } + ALOGD("%s: multiplier:%d", __FUNCTION__, multiplier); + wifiHandle = getWifiHandle(handle); + cmd = new WifihalGeneric(wifiHandle, get_requestid(), OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + if (cmd == NULL) { + ALOGE("%s: Error WifihalGeneric NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + /* Create the NL message. */ + ret = cmd->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to create NL msg. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + ifaceInfo = getIfaceInfo(handle); + if (!ifaceInfo) { + ALOGE("%s: getIfaceInfo is NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = cmd->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to set iface id. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = cmd->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: failed attr_start for VENDOR_DATA", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, multiplier); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to put vendor data. Error:%d", __FUNCTION__, ret); + goto cleanup; + } + cmd->attr_end(nlData); + + /* Send the NL msg. */ + ret = cmd->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + if (cmd) + delete cmd; + return ret; +} + +/*initialize function pointer table with Qualcomm HAL API*/ +wifi_error init_wifi_vendor_hal_func_table(wifi_hal_fn *fn) { + if (fn == NULL) { + return WIFI_ERROR_UNKNOWN; + } + + fn->wifi_initialize = wifi_initialize; + fn->wifi_wait_for_driver_ready = wifi_wait_for_driver_ready; + fn->wifi_cleanup = wifi_cleanup; + fn->wifi_event_loop = wifi_event_loop; + fn->wifi_get_supported_feature_set = wifi_get_supported_feature_set; + fn->wifi_get_concurrency_matrix = wifi_get_concurrency_matrix; + fn->wifi_set_scanning_mac_oui = wifi_set_scanning_mac_oui; + fn->wifi_get_ifaces = wifi_get_ifaces; + fn->wifi_get_iface_name = wifi_get_iface_name; + fn->wifi_set_iface_event_handler = wifi_set_iface_event_handler; + fn->wifi_reset_iface_event_handler = wifi_reset_iface_event_handler; + fn->wifi_start_gscan = wifi_start_gscan; + fn->wifi_stop_gscan = wifi_stop_gscan; + fn->wifi_get_cached_gscan_results = wifi_get_cached_gscan_results; + fn->wifi_set_bssid_hotlist = wifi_set_bssid_hotlist; + fn->wifi_reset_bssid_hotlist = wifi_reset_bssid_hotlist; + fn->wifi_set_significant_change_handler = wifi_set_significant_change_handler; + fn->wifi_reset_significant_change_handler = wifi_reset_significant_change_handler; + fn->wifi_get_gscan_capabilities = wifi_get_gscan_capabilities; + fn->wifi_set_link_stats = wifi_set_link_stats; + fn->wifi_get_link_stats = wifi_get_link_stats; + fn->wifi_clear_link_stats = wifi_clear_link_stats; + fn->wifi_get_valid_channels = wifi_get_valid_channels; + fn->wifi_rtt_range_request = wifi_rtt_range_request; + fn->wifi_rtt_range_cancel = wifi_rtt_range_cancel; + fn->wifi_get_rtt_capabilities = wifi_get_rtt_capabilities; + fn->wifi_rtt_get_responder_info = wifi_rtt_get_responder_info; + fn->wifi_enable_responder = wifi_enable_responder; + fn->wifi_disable_responder = wifi_disable_responder; + fn->wifi_set_nodfs_flag = wifi_set_nodfs_flag; + fn->wifi_start_logging = wifi_start_logging; + fn->wifi_set_epno_list = wifi_set_epno_list; + fn->wifi_reset_epno_list = wifi_reset_epno_list; + fn->wifi_set_country_code = wifi_set_country_code; + fn->wifi_enable_tdls = wifi_enable_tdls; + fn->wifi_disable_tdls = wifi_disable_tdls; + fn->wifi_get_tdls_status = wifi_get_tdls_status; + fn->wifi_get_tdls_capabilities = wifi_get_tdls_capabilities; + fn->wifi_get_firmware_memory_dump = wifi_get_firmware_memory_dump; + fn->wifi_set_log_handler = wifi_set_log_handler; + fn->wifi_reset_log_handler = wifi_reset_log_handler; + fn->wifi_set_alert_handler = wifi_set_alert_handler; + fn->wifi_reset_alert_handler = wifi_reset_alert_handler; + fn->wifi_get_firmware_version = wifi_get_firmware_version; + fn->wifi_get_ring_buffers_status = wifi_get_ring_buffers_status; + fn->wifi_get_logger_supported_feature_set = wifi_get_logger_supported_feature_set; + fn->wifi_get_ring_data = wifi_get_ring_data; + fn->wifi_get_driver_version = wifi_get_driver_version; + fn->wifi_set_passpoint_list = wifi_set_passpoint_list; + fn->wifi_reset_passpoint_list = wifi_reset_passpoint_list; + fn->wifi_set_lci = wifi_set_lci; + fn->wifi_set_lcr = wifi_set_lcr; + fn->wifi_start_sending_offloaded_packet = + wifi_start_sending_offloaded_packet; + fn->wifi_stop_sending_offloaded_packet = wifi_stop_sending_offloaded_packet; + fn->wifi_start_rssi_monitoring = wifi_start_rssi_monitoring; + fn->wifi_stop_rssi_monitoring = wifi_stop_rssi_monitoring; + fn->wifi_nan_enable_request = nan_enable_request; + fn->wifi_nan_disable_request = nan_disable_request; + fn->wifi_nan_publish_request = nan_publish_request; + fn->wifi_nan_publish_cancel_request = nan_publish_cancel_request; + fn->wifi_nan_subscribe_request = nan_subscribe_request; + fn->wifi_nan_subscribe_cancel_request = nan_subscribe_cancel_request; + fn->wifi_nan_transmit_followup_request = nan_transmit_followup_request; + fn->wifi_nan_stats_request = nan_stats_request; + fn->wifi_nan_config_request = nan_config_request; + fn->wifi_nan_tca_request = nan_tca_request; + fn->wifi_nan_beacon_sdf_payload_request = nan_beacon_sdf_payload_request; + fn->wifi_nan_register_handler = nan_register_handler; + fn->wifi_nan_get_version = nan_get_version; + fn->wifi_set_packet_filter = wifi_set_packet_filter; + fn->wifi_get_packet_filter_capabilities = wifi_get_packet_filter_capabilities; + fn->wifi_read_packet_filter = wifi_read_packet_filter; + fn->wifi_nan_get_capabilities = nan_get_capabilities; + fn->wifi_nan_data_interface_create = nan_data_interface_create; + fn->wifi_nan_data_interface_delete = nan_data_interface_delete; + fn->wifi_nan_data_request_initiator = nan_data_request_initiator; + fn->wifi_nan_data_indication_response = nan_data_indication_response; + fn->wifi_nan_data_end = nan_data_end; + fn->wifi_configure_nd_offload = wifi_configure_nd_offload; + fn->wifi_get_driver_memory_dump = wifi_get_driver_memory_dump; + fn->wifi_get_wake_reason_stats = wifi_get_wake_reason_stats; + fn->wifi_start_pkt_fate_monitoring = wifi_start_pkt_fate_monitoring; + fn->wifi_get_tx_pkt_fates = wifi_get_tx_pkt_fates; + fn->wifi_get_rx_pkt_fates = wifi_get_rx_pkt_fates; + fn->wifi_get_roaming_capabilities = wifi_get_roaming_capabilities; + fn->wifi_configure_roaming = wifi_configure_roaming; + fn->wifi_enable_firmware_roaming = wifi_enable_firmware_roaming; + fn->wifi_select_tx_power_scenario = wifi_select_tx_power_scenario; + fn->wifi_reset_tx_power_scenario = wifi_reset_tx_power_scenario; + fn->wifi_set_radio_mode_change_handler = wifi_set_radio_mode_change_handler; + /* Customers will uncomment when they want to set qpower*/ + //fn->wifi_set_qpower = wifi_set_qpower; + fn->wifi_virtual_interface_create = wifi_virtual_interface_create; + fn->wifi_virtual_interface_delete = wifi_virtual_interface_delete; + fn->wifi_set_latency_mode = wifi_set_latency_mode; + fn->wifi_set_thermal_mitigation_mode = wifi_set_thermal_mitigation_mode; + fn->wifi_multi_sta_set_primary_connection = wifi_multi_sta_set_primary_connection; + fn->wifi_multi_sta_set_use_case = wifi_multi_sta_set_use_case; + fn->wifi_set_coex_unsafe_channels = wifi_set_coex_unsafe_channels; + fn->wifi_set_dtim_config = wifi_set_dtim_config; + + return WIFI_SUCCESS; +} + +static void cld80211lib_cleanup(hal_info *info) +{ + if (!info->cldctx) + return; + cld80211_remove_mcast_group(info->cldctx, "host_logs"); + cld80211_remove_mcast_group(info->cldctx, "fw_logs"); + cld80211_remove_mcast_group(info->cldctx, "per_pkt_stats"); + cld80211_remove_mcast_group(info->cldctx, "diag_events"); + cld80211_remove_mcast_group(info->cldctx, "fatal_events"); + cld80211_remove_mcast_group(info->cldctx, "oem_msgs"); + exit_cld80211_recv(info->cldctx); + cld80211_deinit(info->cldctx); + info->cldctx = NULL; +} + +static int wifi_get_iface_id(hal_info *info, const char *iface) +{ + int i; + for (i = 0; i < info->num_interfaces; i++) + if (!strcmp(info->interfaces[i]->name, iface)) + return i; + return -1; +} + +wifi_error wifi_initialize(wifi_handle *handle) +{ + wifi_error ret = WIFI_SUCCESS; + wifi_interface_handle iface_handle; + struct nl_sock *cmd_sock = NULL; + struct nl_sock *event_sock = NULL; + struct nl_cb *cb = NULL; + int status = 0; + int index; + char hw_ver_type[MAX_HW_VER_LENGTH]; + char *hw_name = NULL; + + ALOGI("Initializing wifi"); + hal_info *info = (hal_info *)malloc(sizeof(hal_info)); + if (info == NULL) { + ALOGE("Could not allocate hal_info"); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + memset(info, 0, sizeof(*info)); + + cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT, + NETLINK_GENERIC); + if (cmd_sock == NULL) { + ALOGE("Failed to create command socket port"); + ret = WIFI_ERROR_UNKNOWN; + goto unload; + } + + /* Set the socket buffer size */ + if (nl_socket_set_buffer_size(cmd_sock, (256*1024), 0) < 0) { + ALOGE("Could not set nl_socket RX buffer size for cmd_sock: %s", + strerror(errno)); + /* continue anyway with the default (smaller) buffer */ + } + + event_sock = + wifi_create_nl_socket(WIFI_HAL_EVENT_SOCK_PORT, NETLINK_GENERIC); + if (event_sock == NULL) { + ALOGE("Failed to create event socket port"); + ret = WIFI_ERROR_UNKNOWN; + goto unload; + } + + /* Set the socket buffer size */ + if (nl_socket_set_buffer_size(event_sock, (256*1024), 0) < 0) { + ALOGE("Could not set nl_socket RX buffer size for event_sock: %s", + strerror(errno)); + /* continue anyway with the default (smaller) buffer */ + } + + cb = nl_socket_get_cb(event_sock); + if (cb == NULL) { + ALOGE("Failed to get NL control block for event socket port"); + ret = WIFI_ERROR_UNKNOWN; + goto unload; + } + + info->event_sock_arg = 1; + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &info->event_sock_arg); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &info->event_sock_arg); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &info->event_sock_arg); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, internal_valid_message_handler, + info); + nl_cb_put(cb); + + info->cmd_sock = cmd_sock; + info->event_sock = event_sock; + info->clean_up = false; + info->in_event_loop = false; + + info->event_cb = (cb_info *)malloc(sizeof(cb_info) * DEFAULT_EVENT_CB_SIZE); + if (info->event_cb == NULL) { + ALOGE("Could not allocate event_cb"); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto unload; + } + info->alloc_event_cb = DEFAULT_EVENT_CB_SIZE; + info->num_event_cb = 0; + + info->nl80211_family_id = genl_ctrl_resolve(cmd_sock, "nl80211"); + if (info->nl80211_family_id < 0) { + ALOGE("Could not resolve nl80211 familty id"); + ret = WIFI_ERROR_UNKNOWN; + goto unload; + } + + pthread_mutex_init(&info->cb_lock, NULL); + pthread_mutex_init(&info->pkt_fate_stats_lock, NULL); + + *handle = (wifi_handle) info; + + wifi_add_membership(*handle, "scan"); + wifi_add_membership(*handle, "mlme"); + wifi_add_membership(*handle, "regulatory"); + wifi_add_membership(*handle, "vendor"); + + info->wifihal_ctrl_sock.s = 0; + + wifi_create_ctrl_socket(info); + + //! Initailise the monitoring clients list + INITIALISE_LIST(&info->monitor_sockets); + + info->cldctx = cld80211_init(); + if (info->cldctx != NULL) { + info->user_sock = info->cldctx->sock; + ret = wifi_init_cld80211_sock_cb(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Could not set cb for CLD80211 family"); + goto cld80211_cleanup; + } + + status = cld80211_add_mcast_group(info->cldctx, "host_logs"); + if (status) { + ALOGE("Failed to add mcast group host_logs :%d", status); + goto cld80211_cleanup; + } + status = cld80211_add_mcast_group(info->cldctx, "fw_logs"); + if (status) { + ALOGE("Failed to add mcast group fw_logs :%d", status); + goto cld80211_cleanup; + } + status = cld80211_add_mcast_group(info->cldctx, "per_pkt_stats"); + if (status) { + ALOGE("Failed to add mcast group per_pkt_stats :%d", status); + goto cld80211_cleanup; + } + status = cld80211_add_mcast_group(info->cldctx, "diag_events"); + if (status) { + ALOGE("Failed to add mcast group diag_events :%d", status); + goto cld80211_cleanup; + } + status = cld80211_add_mcast_group(info->cldctx, "fatal_events"); + if (status) { + ALOGE("Failed to add mcast group fatal_events :%d", status); + goto cld80211_cleanup; + } + + if(info->wifihal_ctrl_sock.s > 0) + { + status = cld80211_add_mcast_group(info->cldctx, "oem_msgs"); + if (status) { + ALOGE("Failed to add mcast group oem_msgs :%d", status); + goto cld80211_cleanup; + } + } + } else { + ret = wifi_init_user_sock(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to alloc user socket"); + goto unload; + } + } + + ret = wifi_init_interfaces(*handle); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to init interfaces"); + goto unload; + } + + if (info->num_interfaces == 0) { + ALOGE("No interfaces found"); + ret = WIFI_ERROR_UNINITIALIZED; + goto unload; + } + + index = wifi_get_iface_id(info, "wlan0"); + if (index == -1) { + int i; + for (i = 0; i < info->num_interfaces; i++) + { + free(info->interfaces[i]); + } + ALOGE("%s no iface with wlan0", __func__); + goto unload; + } + iface_handle = (wifi_interface_handle)info->interfaces[index]; + + ret = acquire_supported_features(iface_handle, + &info->supported_feature_set); + if (ret != WIFI_SUCCESS) { + ALOGI("Failed to get supported feature set : %d", ret); + //acquire_supported_features failure is acceptable condition as legacy + //drivers might not support the required vendor command. So, do not + //consider it as failure of wifi_initialize + ret = WIFI_SUCCESS; + } + + ret = acquire_driver_supported_features(iface_handle, + &info->driver_supported_features); + if (ret != WIFI_SUCCESS) { + ALOGI("Failed to get vendor feature set : %d", ret); + ret = WIFI_SUCCESS; + } + + ret = wifi_get_logger_supported_feature_set(iface_handle, + &info->supported_logger_feature_set); + if (ret != WIFI_SUCCESS) + ALOGE("Failed to get supported logger feature set: %d", ret); + + ret = wifi_get_firmware_version(iface_handle, hw_ver_type, + MAX_HW_VER_LENGTH); + if (ret == WIFI_SUCCESS) { + hw_name = strstr(hw_ver_type, "HW:"); + if (hw_name) { + hw_name += strlen("HW:"); + if (strncmp(hw_name, "QCA6174", 7) == 0) + info->pkt_log_ver = PKT_LOG_V1; + else + info->pkt_log_ver = PKT_LOG_V2; + } else { + info->pkt_log_ver = PKT_LOG_V0; + } + ALOGV("%s: hardware version type %d", __func__, info->pkt_log_ver); + } else { + ALOGE("Failed to get firmware version: %d", ret); + } + + ret = get_firmware_bus_max_size_supported(iface_handle); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to get supported bus size, error : %d", ret); + info->firmware_bus_max_size = 1520; + } + + ret = wifi_logger_ring_buffers_init(info); + if (ret != WIFI_SUCCESS) + ALOGE("Wifi Logger Ring Initialization Failed"); + + ret = wifi_get_capabilities(iface_handle); + if (ret != WIFI_SUCCESS) + ALOGE("Failed to get wifi Capabilities, error: %d", ret); + + info->pkt_stats = (struct pkt_stats_s *)malloc(sizeof(struct pkt_stats_s)); + if (!info->pkt_stats) { + ALOGE("%s: malloc Failed for size: %zu", + __FUNCTION__, sizeof(struct pkt_stats_s)); + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto unload; + } + + info->rx_buf_size_allocated = MAX_RXMPDUS_PER_AMPDU * MAX_MSDUS_PER_MPDU + * PKT_STATS_BUF_SIZE; + + info->rx_aggr_pkts = + (wifi_ring_buffer_entry *)malloc(info->rx_buf_size_allocated); + if (!info->rx_aggr_pkts) { + ALOGE("%s: malloc Failed for size: %d", + __FUNCTION__, info->rx_buf_size_allocated); + ret = WIFI_ERROR_OUT_OF_MEMORY; + info->rx_buf_size_allocated = 0; + goto unload; + } + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_allocated); + + info->exit_sockets[0] = -1; + info->exit_sockets[1] = -1; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->exit_sockets) == -1) { + ALOGE("Failed to create exit socket pair"); + ret = WIFI_ERROR_UNKNOWN; + goto unload; + } + + ALOGV("Initializing Gscan Event Handlers"); + ret = initializeGscanHandlers(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Initializing Gscan Event Handlers Failed"); + goto unload; + } + + ret = initializeRSSIMonitorHandler(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Initializing RSSI Event Handler Failed"); + goto unload; + } + + ret = initializeRadioHandler(info); + if (ret != WIFI_SUCCESS) { + ALOGE("Initializing Radio Event handler Failed"); + goto unload; + } + + ret = wifi_init_tcp_param_change_event_handler(iface_handle); + if (ret != WIFI_SUCCESS) { + ALOGE("Initializing TCP param change event Handler Failed"); + goto unload; + } + + ALOGV("Initialized Wifi HAL Successfully; vendor cmd = %d Supported" + " features : %" PRIx64, NL80211_CMD_VENDOR, info->supported_feature_set); + + if (wifi_is_nan_ext_cmd_supported(iface_handle)) + info->support_nan_ext_cmd = true; + else + info->support_nan_ext_cmd = false; + + ALOGV("support_nan_ext_cmd is %d", + info->support_nan_ext_cmd); + +cld80211_cleanup: + if (status != 0 || ret != WIFI_SUCCESS) { + ret = WIFI_ERROR_UNKNOWN; + cld80211lib_cleanup(info); + } +unload: + if (ret != WIFI_SUCCESS) { + if (cmd_sock) + nl_socket_free(cmd_sock); + if (event_sock) + nl_socket_free(event_sock); + if (info) { + if (info->cldctx) { + cld80211lib_cleanup(info); + } else if (info->user_sock) { + nl_socket_free(info->user_sock); + } + if (info->pkt_stats) free(info->pkt_stats); + if (info->rx_aggr_pkts) free(info->rx_aggr_pkts); + wifi_logger_ring_buffers_deinit(info); + cleanupGscanHandlers(info); + cleanupRSSIMonitorHandler(info); + cleanupRadioHandler(info); + cleanupTCPParamCommand(info); + free(info->event_cb); + if (info->driver_supported_features.flags) { + free(info->driver_supported_features.flags); + info->driver_supported_features.flags = NULL; + } + free(info); + } + } + + return ret; +} + +#ifdef WIFI_DRIVER_STATE_CTRL_PARAM +static int wifi_update_driver_state(const char *state) { + struct timespec ts; + int len, fd, ret = 0, count = 5; + ts.tv_sec = 0; + ts.tv_nsec = 200 * 1000000L; + do { + if (access(WIFI_DRIVER_STATE_CTRL_PARAM, W_OK) == 0) + break; + nanosleep(&ts, (struct timespec *)NULL); + } while (--count > 0); /* wait at most 1 second for completion. */ + if (count == 0) { + ALOGE("Failed to access driver state control param %s, %d at %s", + strerror(errno), errno, WIFI_DRIVER_STATE_CTRL_PARAM); + return -1; + } + fd = TEMP_FAILURE_RETRY(open(WIFI_DRIVER_STATE_CTRL_PARAM, O_WRONLY)); + if (fd < 0) { + ALOGE("Failed to open driver state control param at %s", + WIFI_DRIVER_STATE_CTRL_PARAM); + return -1; + } + len = strlen(state) + 1; + if (TEMP_FAILURE_RETRY(write(fd, state, len)) != len) { + ALOGE("Failed to write driver state control param at %s", + WIFI_DRIVER_STATE_CTRL_PARAM); + ret = -1; + } + close(fd); + return ret; +} +#endif + +wifi_error wifi_wait_for_driver_ready(void) +{ + // This function will wait to make sure basic client netdev is created + // Function times out after 10 seconds + int count = (POLL_DRIVER_MAX_TIME_MS * 1000) / POLL_DRIVER_DURATION_US; + FILE *fd; + +#if defined(WIFI_DRIVER_STATE_CTRL_PARAM) && defined(WIFI_DRIVER_STATE_ON) + if (wifi_update_driver_state(WIFI_DRIVER_STATE_ON) < 0) { + return WIFI_ERROR_UNKNOWN; + } +#endif + + do { + if ((fd = fopen("/sys/class/net/wlan0", "r")) != NULL) { + fclose(fd); + return WIFI_SUCCESS; + } + usleep(POLL_DRIVER_DURATION_US); + } while(--count > 0); + + ALOGE("Timed out wating on Driver ready ... "); + return WIFI_ERROR_TIMED_OUT; +} + +static int wifi_add_membership(wifi_handle handle, const char *group) +{ + hal_info *info = getHalInfo(handle); + + int id = wifi_get_multicast_id(handle, "nl80211", group); + if (id < 0) { + ALOGE("Could not find group %s", group); + return id; + } + + int ret = nl_socket_add_membership(info->event_sock, id); + if (ret < 0) { + ALOGE("Could not add membership to group %s", group); + } + + return ret; +} + +static void internal_cleaned_up_handler(wifi_handle handle) +{ + hal_info *info = getHalInfo(handle); + wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler; + wifihal_mon_sock_t *reg, *tmp; + + if (info->cmd_sock != 0) { + nl_socket_free(info->cmd_sock); + nl_socket_free(info->event_sock); + info->cmd_sock = NULL; + info->event_sock = NULL; + } + + if (info->wifihal_ctrl_sock.s != 0) { + close(info->wifihal_ctrl_sock.s); + unlink(info->wifihal_ctrl_sock.local.sun_path); + info->wifihal_ctrl_sock.s = 0; + } + + list_for_each_entry_safe(reg, tmp, &info->monitor_sockets, list) { + del_from_list(®->list); + free(reg); + } + + if (info->interfaces) { + for (int i = 0; i < info->num_interfaces; i++) + free(info->interfaces[i]); + free(info->interfaces); + } + + if (info->cldctx != NULL) { + cld80211lib_cleanup(info); + } else if (info->user_sock != 0) { + nl_socket_free(info->user_sock); + info->user_sock = NULL; + } + + if (info->pkt_stats) + free(info->pkt_stats); + if (info->rx_aggr_pkts) + free(info->rx_aggr_pkts); + wifi_logger_ring_buffers_deinit(info); + cleanupGscanHandlers(info); + cleanupRSSIMonitorHandler(info); + cleanupRadioHandler(info); + cleanupTCPParamCommand(info); + + if (info->num_event_cb) + ALOGE("%d events were leftover without being freed", + info->num_event_cb); + free(info->event_cb); + + if (info->exit_sockets[0] >= 0) { + close(info->exit_sockets[0]); + info->exit_sockets[0] = -1; + } + + if (info->exit_sockets[1] >= 0) { + close(info->exit_sockets[1]); + info->exit_sockets[1] = -1; + } + + if (info->pkt_fate_stats) { + free(info->pkt_fate_stats); + info->pkt_fate_stats = NULL; + } + + if (info->driver_supported_features.flags) { + free(info->driver_supported_features.flags); + info->driver_supported_features.flags = NULL; + } + + (*cleaned_up_handler)(handle); + pthread_mutex_destroy(&info->cb_lock); + pthread_mutex_destroy(&info->pkt_fate_stats_lock); + free(info); +} + +void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler) +{ + if (!handle) { + ALOGE("Handle is null"); + return; + } + + hal_info *info = getHalInfo(handle); + info->cleaned_up_handler = handler; + // Remove the dynamically created interface during wifi cleanup. + wifi_cleanup_dynamic_ifaces(handle); + + TEMP_FAILURE_RETRY(write(info->exit_sockets[0], "E", 1)); + + // Ensure wifi_event_loop() exits by setting clean_up to true. + info->clean_up = true; + ALOGI("Sent msg on exit sock to unblock poll()"); +} + + + +static int validate_cld80211_msg(nlmsghdr *nlh, int family, int cmd) +{ + //! Enhance this API + struct genlmsghdr *hdr; + hdr = (genlmsghdr *)nlmsg_data(nlh); + + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(wifihal_ctrl_req_t)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } + if(hdr->cmd == WLAN_NL_MSG_OEM) + { + ALOGV("%s: FAMILY ID : %d ,NL CMD : %d received", __FUNCTION__, + nlh->nlmsg_type, hdr->cmd); + + //! Update pid with the wifihal pid + nlh->nlmsg_pid = getpid(); + return 0; + } + else + { + ALOGE("%s: NL CMD : %d received is not allowed", __FUNCTION__, hdr->cmd); + return -1; + } +} + + +static int validate_genl_msg(nlmsghdr *nlh, int family, int cmd) +{ + //! Enhance this API + struct genlmsghdr *hdr; + hdr = (genlmsghdr *)nlmsg_data(nlh); + + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(wifihal_ctrl_req_t)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } + if(hdr->cmd == NL80211_CMD_FRAME || + hdr->cmd == NL80211_CMD_REGISTER_ACTION) + { + ALOGV("%s: FAMILY ID : %d ,NL CMD : %d received", __FUNCTION__, + nlh->nlmsg_type, hdr->cmd); + return 0; + } + else + { + ALOGE("%s: NL CMD : %d received is not allowed", __FUNCTION__, hdr->cmd); + return -1; + } +} + +static int send_nl_data(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg) +{ + hal_info *info = getHalInfo(handle); + struct nl_msg *msg = NULL; + int retval = -1; + + //! attach monitor socket if it was not it the list + if(ctrl_msg->monsock_len) + { + retval = attach_monitor_sock(handle, ctrl_msg); + if(retval) + goto nl_out; + } + + msg = nlmsg_alloc(); + if (!msg) + { + ALOGE("%s: Memory allocation failed \n", __FUNCTION__); + goto nl_out; + } + + if (ctrl_msg->data_len > nlmsg_get_max_size(msg)) + { + ALOGE("%s: Invalid ctrl msg length \n", __FUNCTION__); + retval = -1; + goto nl_out; + } + memcpy((char *)msg->nm_nlh, (char *)ctrl_msg->data, ctrl_msg->data_len); + + if(ctrl_msg->family_name == GENERIC_NL_FAMILY) + { + //! Before sending the received gennlmsg to kernel, + //! better to have checks for allowed commands + retval = validate_genl_msg(msg->nm_nlh, ctrl_msg->family_name, ctrl_msg->cmd_id); + if (retval < 0) + goto nl_out; + + retval = nl_send_auto_complete(info->event_sock, msg); /* send message */ + if (retval < 0) + { + ALOGE("%s: nl_send_auto_complete - failed : %d \n", __FUNCTION__, retval); + goto nl_out; + } + ALOGI("%s: sent gennl msg of len: %d to driver\n", __FUNCTION__, ctrl_msg->data_len); + retval = internal_pollin_handler(handle, info->event_sock); + } + else if (ctrl_msg->family_name == CLD80211_FAMILY) + { + if (info->cldctx != NULL) + { + //! Before sending the received cld80211 msg to kernel, + //! better to have checks for allowed commands + retval = validate_cld80211_msg(msg->nm_nlh, ctrl_msg->family_name, ctrl_msg->cmd_id); + if (retval < 0) + goto nl_out; + + retval = cld80211_send_msg(info->cldctx, msg); + if (retval != 0) + { + ALOGE("%s: send cld80211 message - failed\n", __FUNCTION__); + goto nl_out; + } + ALOGI("%s: sent cld80211 msg of len: %d to driver\n", __FUNCTION__, ctrl_msg->data_len); + } + else + { + ALOGE("%s: cld80211 ctx not present \n", __FUNCTION__); + } + } + else + { + ALOGE("%s: Unknown family name : %d \n", __FUNCTION__, ctrl_msg->family_name); + retval = -1; + } +nl_out: + if (msg) + { + nlmsg_free(msg); + } + return retval; +} + +static int register_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg, int attach) +{ + hal_info *info = getHalInfo(handle); + + wifihal_mon_sock_t *reg, *nreg; + char *match = NULL; + unsigned int match_len = 0; + unsigned int type; + + //! For Register Action frames, compare the match length and match buffer. + //! For other registrations such as oem messages, + //! diag messages check for respective commands + + if((ctrl_msg->family_name == GENERIC_NL_FAMILY) && + (ctrl_msg->cmd_id == NL80211_CMD_REGISTER_ACTION)) + { + struct genlmsghdr *genlh; + struct nlmsghdr *nlh = (struct nlmsghdr *)ctrl_msg->data; + genlh = (struct genlmsghdr *)nlmsg_data(nlh); + struct nlattr *nlattrs[NL80211_ATTR_MAX + 1]; + + if (nlh->nlmsg_len > DEFAULT_PAGE_SIZE - sizeof(*ctrl_msg)) + { + ALOGE("%s: Invalid nlmsg length", __FUNCTION__); + return -1; + } + if (nla_parse(nlattrs, NL80211_ATTR_MAX, genlmsg_attrdata(genlh, 0), + genlmsg_attrlen(genlh, 0), NULL)) + { + ALOGE("unable to parse nl attributes"); + return -1; + } + if (!nlattrs[NL80211_ATTR_FRAME_TYPE]) + { + ALOGD("No Valid frame type"); + } + else + { + type = nla_get_u16(nlattrs[NL80211_ATTR_FRAME_TYPE]); + } + if (!nlattrs[NL80211_ATTR_FRAME_MATCH]) + { + ALOGE("No Frame Match"); + return -1; + } + else + { + match_len = nla_len(nlattrs[NL80211_ATTR_FRAME_MATCH]); + match = (char *)nla_data(nlattrs[NL80211_ATTR_FRAME_MATCH]); + + list_for_each_entry(reg, &info->monitor_sockets, list) { + + int mlen = min(match_len, reg->match_len); + + if (reg->match_len == 0) + continue; + + if (memcmp(reg->match, match, mlen) == 0) { + + if((ctrl_msg->monsock_len == reg->monsock_len) && + (memcmp((char *)®->monsock, (char *)&ctrl_msg->monsock, ctrl_msg->monsock_len) == 0)) + { + if(attach) + { + ALOGE(" %s :Action frame already registered for this client ", __FUNCTION__); + return -2; + } + else + { + del_from_list(®->list); + free(reg); + return 0; + } + } + else + { + //! when action frame registered for other client, + //! you can't attach or dettach for new client + ALOGE(" %s :Action frame registered for other client ", __FUNCTION__); + return -2; + } + } + } + } + } + else + { + list_for_each_entry(reg, &info->monitor_sockets, list) { + + //! Checking for monitor sock in the list : + + //! For attach request : + //! if sock is not present, then it is a new entry , so add to list. + //! if sock is present, and cmd_id does not match, add another entry to list. + //! if sock is present, and cmd_id matches, return 0. + + //! For dettach req : + //! if sock is not present, return error -2. + //! if sock is present, and cmd_id does not match, return error -2. + //! if sock is present, and cmd_id matches, delete entry and return 0. + + if (ctrl_msg->monsock_len != reg->monsock_len) + continue; + + if (memcmp((char *)®->monsock, (char *)&ctrl_msg->monsock, ctrl_msg->monsock_len) == 0) { + + if((reg->family_name == ctrl_msg->family_name) && (reg->cmd_id == ctrl_msg->cmd_id)) + { + if(!attach) + { + del_from_list(®->list); + free(reg); + } + return 0; + } + } + } + } + + if(attach) + { + if (ctrl_msg->monsock_len > sizeof(struct sockaddr_un)) + { + ALOGE("%s: Invalid monitor socket length \n", __FUNCTION__); + return -3; + } + + nreg = (wifihal_mon_sock_t *)malloc(sizeof(*reg) + match_len); + if (!nreg) + return -1; + + memset((char *)nreg, 0, sizeof(*reg) + match_len); + nreg->family_name = ctrl_msg->family_name; + nreg->cmd_id = ctrl_msg->cmd_id; + nreg->monsock_len = ctrl_msg->monsock_len; + memcpy((char *)&nreg->monsock, (char *)&ctrl_msg->monsock, ctrl_msg->monsock_len); + + if(match_len && match) + { + nreg->match_len = match_len; + memcpy(nreg->match, match, match_len); + } + add_to_list(&nreg->list, &info->monitor_sockets); + } + else + { + //! Not attached, so cant be dettached + ALOGE("%s: Dettaching the unregistered socket \n", __FUNCTION__); + return -2; + } + + return 0; +} + +static int attach_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg) +{ + return register_monitor_sock(handle, ctrl_msg, 1); +} + +static int dettach_monitor_sock(wifi_handle handle, wifihal_ctrl_req_t *ctrl_msg) +{ + return register_monitor_sock(handle, ctrl_msg, 0); +} + +static int internal_pollin_handler_app(wifi_handle handle, struct ctrl_sock *sock) +{ + int retval = -1; + int res; + struct sockaddr_un from; + socklen_t fromlen = sizeof(from); + wifihal_ctrl_req_t *ctrl_msg; + wifihal_ctrl_sync_rsp_t ctrl_reply; + + ctrl_msg = (wifihal_ctrl_req_t *)malloc(DEFAULT_PAGE_SIZE); + if(ctrl_msg == NULL) + { + ALOGE ("Memory allocation failure"); + return -1; + } + + memset((char *)ctrl_msg, 0, DEFAULT_PAGE_SIZE); + + res = recvfrom(sock->s, (char *)ctrl_msg, DEFAULT_PAGE_SIZE, 0, + (struct sockaddr *)&from, &fromlen); + if (res < 0) { + ALOGE("recvfrom(ctrl_iface): %s", + strerror(errno)); + if(ctrl_msg) + free(ctrl_msg); + + return 0; + } + switch(ctrl_msg->ctrl_cmd) + { + case WIFIHAL_CTRL_MONITOR_ATTACH: + retval = attach_monitor_sock(handle, ctrl_msg); + break; + case WIFIHAL_CTRL_MONITOR_DETTACH: + retval = dettach_monitor_sock(handle, ctrl_msg); + break; + case WIFIHAL_CTRL_SEND_NL_DATA: + retval = send_nl_data(handle, ctrl_msg); + break; + default: + break; + } + + ctrl_reply.ctrl_cmd = ctrl_msg->ctrl_cmd; + ctrl_reply.family_name = ctrl_msg->family_name; + ctrl_reply.cmd_id = ctrl_msg->cmd_id; + ctrl_reply.status = retval; + + if(ctrl_msg) + free(ctrl_msg); + + if (sendto(sock->s, (char *)&ctrl_reply, sizeof(ctrl_reply), 0, (struct sockaddr *)&from, + fromlen) < 0) { + int _errno = errno; + ALOGE("socket send failed : %d",_errno); + + if (_errno == ENOBUFS || _errno == EAGAIN) { + /* + * The socket send buffer could be full. This + * may happen if client programs are not + * receiving their pending messages. Close and + * reopen the socket as a workaround to avoid + * getting stuck being unable to send any new + * responses. + */ + } + } + return res; +} + +static int internal_pollin_handler(wifi_handle handle, struct nl_sock *sock) +{ + struct nl_cb *cb = nl_socket_get_cb(sock); + + int res = nl_recvmsgs(sock, cb); + if(res) + ALOGE("Error :%d while reading nl msg", res); + nl_cb_put(cb); + return res; +} + +static void internal_event_handler_app(wifi_handle handle, int events, + struct ctrl_sock *sock) +{ + if (events & POLLERR) { + ALOGE("Error reading from wifi_hal ctrl socket"); + internal_pollin_handler_app(handle, sock); + } else if (events & POLLHUP) { + ALOGE("Remote side hung up"); + } else if (events & POLLIN) { + //ALOGI("Found some events!!!"); + internal_pollin_handler_app(handle, sock); + } else { + ALOGE("Unknown event - %0x", events); + } +} + +static void internal_event_handler(wifi_handle handle, int events, + struct nl_sock *sock) +{ + if (events & POLLERR) { + ALOGE("Error reading from socket"); + internal_pollin_handler(handle, sock); + } else if (events & POLLHUP) { + ALOGE("Remote side hung up"); + } else if (events & POLLIN) { + //ALOGI("Found some events!!!"); + internal_pollin_handler(handle, sock); + } else { + ALOGE("Unknown event - %0x", events); + } +} + +static bool exit_event_handler(int fd) { + char buf[4]; + memset(buf, 0, sizeof(buf)); + + TEMP_FAILURE_RETRY(read(fd, buf, sizeof(buf))); + ALOGI("exit_event_handler, buf=%s", buf); + if (strncmp(buf, "E", 1) == 0) { + return true; + } + + return false; +} + +/* Run event handler */ +void wifi_event_loop(wifi_handle handle) +{ + hal_info *info = getHalInfo(handle); + if (info->in_event_loop) { + return; + } else { + info->in_event_loop = true; + } + + pollfd pfd[4]; + memset(&pfd, 0, 4*sizeof(pfd[0])); + + pfd[0].fd = nl_socket_get_fd(info->event_sock); + pfd[0].events = POLLIN; + + pfd[1].fd = nl_socket_get_fd(info->user_sock); + pfd[1].events = POLLIN; + + pfd[2].fd = info->exit_sockets[1]; + pfd[2].events = POLLIN; + + if(info->wifihal_ctrl_sock.s > 0) { + pfd[3].fd = info->wifihal_ctrl_sock.s ; + pfd[3].events = POLLIN; + } + /* TODO: Add support for timeouts */ + + do { + pfd[0].revents = 0; + pfd[1].revents = 0; + pfd[2].revents = 0; + pfd[3].revents = 0; + //ALOGI("Polling sockets"); + int result = poll(pfd, 4, -1); + if (result < 0) { + ALOGE("Error polling socket"); + } else { + if (pfd[0].revents & (POLLIN | POLLHUP | POLLERR)) { + internal_event_handler(handle, pfd[0].revents, info->event_sock); + } + if (pfd[1].revents & (POLLIN | POLLHUP | POLLERR)) { + internal_event_handler(handle, pfd[1].revents, info->user_sock); + } + if ((info->wifihal_ctrl_sock.s > 0) && (pfd[3].revents & (POLLIN | POLLHUP | POLLERR))) { + internal_event_handler_app(handle, pfd[3].revents, &info->wifihal_ctrl_sock); + } + if (pfd[2].revents & POLLIN) { + if (exit_event_handler(pfd[2].fd)) { + break; + } + } + } + rb_timerhandler(info); + } while (!info->clean_up); + internal_cleaned_up_handler(handle); + ALOGI("wifi_event_loop() exits success"); +} + +static int user_sock_message_handler(nl_msg *msg, void *arg) +{ + wifi_handle handle = (wifi_handle)arg; + hal_info *info = getHalInfo(handle); + + diag_message_handler(info, msg); + + return NL_OK; +} + +static int internal_valid_message_handler(nl_msg *msg, void *arg) +{ + wifi_handle handle = (wifi_handle)arg; + hal_info *info = getHalInfo(handle); + + WifiEvent event(msg); + int res = event.parse(); + if (res < 0) { + ALOGE("Failed to parse event: %d", res); + return NL_SKIP; + } + + int cmd = event.get_cmd(); + uint32_t vendor_id = 0; + int subcmd = 0; + + if (cmd == NL80211_CMD_VENDOR) { + vendor_id = event.get_u32(NL80211_ATTR_VENDOR_ID); + subcmd = event.get_u32(NL80211_ATTR_VENDOR_SUBCMD); + /* Restrict printing GSCAN_FULL_RESULT which is causing lot + of logs in bug report */ + if (subcmd != QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT) { + ALOGI("event received %s, vendor_id = 0x%0x, subcmd = 0x%0x", + event.get_cmdString(), vendor_id, subcmd); + } + } + else if((info->wifihal_ctrl_sock.s > 0) && (cmd == NL80211_CMD_FRAME)) + { + struct genlmsghdr *genlh; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + genlh = (struct genlmsghdr *)nlmsg_data(nlh); + struct nlattr *nlattrs[NL80211_ATTR_MAX + 1]; + + wifihal_ctrl_event_t *ctrl_evt; + char *buff; + wifihal_mon_sock_t *reg; + + nla_parse(nlattrs, NL80211_ATTR_MAX, genlmsg_attrdata(genlh, 0), + genlmsg_attrlen(genlh, 0), NULL); + + if (!nlattrs[NL80211_ATTR_FRAME]) + { + ALOGD("No Frame body"); + return WIFI_SUCCESS; + } + ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len); + if(ctrl_evt == NULL) + { + ALOGE("Memory allocation failure"); + return -1; + } + memset((char *)ctrl_evt, 0, sizeof(*ctrl_evt) + nlh->nlmsg_len); + ctrl_evt->family_name = GENERIC_NL_FAMILY; + ctrl_evt->cmd_id = cmd; + ctrl_evt->data_len = nlh->nlmsg_len; + memcpy(ctrl_evt->data, (char *)nlh, ctrl_evt->data_len); + + + buff = (char *)nla_data(nlattrs[NL80211_ATTR_FRAME]) + 24; //! Size of Wlan80211FrameHeader + + list_for_each_entry(reg, &info->monitor_sockets, list) { + + if (memcmp(reg->match, buff, reg->match_len)) + continue; + + /* found match! */ + /* Indicate the received Action frame to respective client */ + ALOGI("send gennl msg of len : %d to apps", ctrl_evt->data_len); + if (sendto(info->wifihal_ctrl_sock.s, (char *)ctrl_evt, + sizeof(*ctrl_evt) + ctrl_evt->data_len, + 0, (struct sockaddr *)®->monsock, reg->monsock_len) < 0) + { + int _errno = errno; + ALOGE("socket send failed : %d",_errno); + + if (_errno == ENOBUFS || _errno == EAGAIN) { + } + } + + } + free(ctrl_evt); + } + + else { + ALOGV("event received %s", event.get_cmdString()); + } + + // event.log(); + + bool dispatched = false; + + pthread_mutex_lock(&info->cb_lock); + + for (int i = 0; i < info->num_event_cb; i++) { + if (cmd == info->event_cb[i].nl_cmd) { + if (cmd == NL80211_CMD_VENDOR + && ((vendor_id != info->event_cb[i].vendor_id) + || (subcmd != info->event_cb[i].vendor_subcmd))) + { + /* event for a different vendor, ignore it */ + continue; + } + + cb_info *cbi = &(info->event_cb[i]); + pthread_mutex_unlock(&info->cb_lock); + if (cbi->cb_func) { + (*(cbi->cb_func))(msg, cbi->cb_arg); + dispatched = true; + } + return NL_OK; + } + } + +#ifdef QC_HAL_DEBUG + if (!dispatched) { + ALOGI("event ignored!!"); + } +#endif + + pthread_mutex_unlock(&info->cb_lock); + return NL_OK; +} + +//////////////////////////////////////////////////////////////////////////////// + +class GetMulticastIdCommand : public WifiCommand +{ +private: + const char *mName; + const char *mGroup; + int mId; +public: + GetMulticastIdCommand(wifi_handle handle, const char *name, + const char *group) : WifiCommand(handle, 0) + { + mName = name; + mGroup = group; + mId = -1; + } + + int getId() { + return mId; + } + + virtual wifi_error create() { + int nlctrlFamily = genl_ctrl_resolve(mInfo->cmd_sock, "nlctrl"); + // ALOGI("ctrl family = %d", nlctrlFamily); + wifi_error ret = mMsg.create(nlctrlFamily, CTRL_CMD_GETFAMILY, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + ret = mMsg.put_string(CTRL_ATTR_FAMILY_NAME, mName); + return ret; + } + + virtual int handleResponse(WifiEvent& reply) { + + // ALOGI("handling reponse in %s", __func__); + + struct nlattr **tb = reply.attributes(); + struct nlattr *mcgrp = NULL; + int i; + + if (!tb[CTRL_ATTR_MCAST_GROUPS]) { + ALOGI("No multicast groups found"); + return NL_SKIP; + } else { + // ALOGI("Multicast groups attr size = %d", + // nla_len(tb[CTRL_ATTR_MCAST_GROUPS])); + } + + for_each_attr(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) { + + // ALOGI("Processing group"); + struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1]; + nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, (nlattr *)nla_data(mcgrp), + nla_len(mcgrp), NULL); + if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || !tb2[CTRL_ATTR_MCAST_GRP_ID]) + { + continue; + } + + char *grpName = (char *)nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]); + int grpNameLen = nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME]); + + // ALOGI("Found group name %s", grpName); + + if (strncmp(grpName, mGroup, grpNameLen) != 0) + continue; + + mId = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]); + break; + } + + return NL_SKIP; + } + +}; + +static int wifi_get_multicast_id(wifi_handle handle, const char *name, + const char *group) +{ + GetMulticastIdCommand cmd(handle, name, group); + int res = cmd.requestResponse(); + if (res < 0) + return res; + else + return cmd.getId(); +} + +///////////////////////////////////////////////////////////////////////// + +static bool is_wifi_interface(const char *name) +{ + // filter out bridge interface + if (strstr(name, "br") != NULL) { + return false; + } + + if (strncmp(name, "wlan", 4) != 0 && strncmp(name, "p2p", 3) != 0 + && strncmp(name, "wifi", 4) != 0 + && strncmp(name, "swlan", 5) != 0) { + /* not a wifi interface; ignore it */ + return false; + } else { + return true; + } +} + +static int get_interface(const char *name, interface_info *info) +{ + strlcpy(info->name, name, (IFNAMSIZ + 1)); + info->id = if_nametoindex(name); + // ALOGI("found an interface : %s, id = %d", name, info->id); + return WIFI_SUCCESS; +} + +wifi_error wifi_init_interfaces(wifi_handle handle) +{ + hal_info *info = (hal_info *)handle; + + struct dirent *de; + + DIR *d = opendir("/sys/class/net"); + if (d == 0) + return WIFI_ERROR_UNKNOWN; + + int n = 0; + while ((de = readdir(d))) { + if (de->d_name[0] == '.') + continue; + if (is_wifi_interface(de->d_name) ) { + n++; + } + } + + closedir(d); + + d = opendir("/sys/class/net"); + if (d == 0) + return WIFI_ERROR_UNKNOWN; + + info->interfaces = (interface_info **)malloc(sizeof(interface_info *) * n); + if (info->interfaces == NULL) { + ALOGE("%s: Error info->interfaces NULL", __func__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + int i = 0; + while ((de = readdir(d))) { + if (de->d_name[0] == '.') + continue; + if (is_wifi_interface(de->d_name)) { + interface_info *ifinfo + = (interface_info *)malloc(sizeof(interface_info)); + if (ifinfo == NULL) { + ALOGE("%s: Error ifinfo NULL", __func__); + while (i > 0) { + free(info->interfaces[i-1]); + i--; + } + free(info->interfaces); + return WIFI_ERROR_OUT_OF_MEMORY; + } + if (get_interface(de->d_name, ifinfo) != WIFI_SUCCESS) { + free(ifinfo); + continue; + } + ifinfo->handle = handle; + info->interfaces[i] = ifinfo; + i++; + } + } + + closedir(d); + + info->num_interfaces = n; + + return WIFI_SUCCESS; +} + +wifi_error wifi_get_ifaces(wifi_handle handle, int *num, + wifi_interface_handle **interfaces) +{ + hal_info *info = (hal_info *)handle; + + /* In case of dynamic interface add/remove, interface handles need to be + * updated so that, interface specific APIs could be instantiated. + * Reload here to get interfaces which are dynamically added. */ + + if (info->num_interfaces > 0) { + for (int i = 0; i < info->num_interfaces; i++) + free(info->interfaces[i]); + free(info->interfaces); + } + + wifi_error ret = wifi_init_interfaces(handle); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to init interfaces while wifi_get_ifaces"); + return ret; + } + + *interfaces = (wifi_interface_handle *)info->interfaces; + *num = info->num_interfaces; + + return WIFI_SUCCESS; +} + +wifi_error wifi_get_iface_name(wifi_interface_handle handle, char *name, + size_t size) +{ + interface_info *info = (interface_info *)handle; + strlcpy(name, info->name, size); + return WIFI_SUCCESS; +} + +/* Get the supported Feature set */ +wifi_error wifi_get_supported_feature_set(wifi_interface_handle iface, + feature_set *set) +{ + int ret = 0; + wifi_handle handle = getWifiHandle(iface); + *set = 0; + hal_info *info = getHalInfo(handle); + + ret = acquire_supported_features(iface, set); + if (ret != WIFI_SUCCESS) { + *set = info->supported_feature_set; + ALOGV("Supported feature set acquired at initialization : %" PRIx64, *set); + } else { + info->supported_feature_set = *set; + ALOGV("Supported feature set acquired : %" PRIx64, *set); + } + return WIFI_SUCCESS; +} + +wifi_error wifi_get_concurrency_matrix(wifi_interface_handle handle, + int set_size_max, + feature_set set[], int *set_size) +{ + wifi_error ret; + struct nlattr *nlData; + WifihalGeneric *vCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + if (set == NULL) { + ALOGE("%s: NULL set pointer provided. Exit.", + __func__); + return WIFI_ERROR_INVALID_ARGS; + } + + vCommand = new WifihalGeneric(wifiHandle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX); + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __func__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX, + set_size_max); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + /* Populate the input received from caller/framework. */ + vCommand->setMaxSetSize(set_size_max); + vCommand->setSizePtr(set_size); + vCommand->setConcurrencySet(set); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse() error: %d", __func__, ret); + +cleanup: + delete vCommand; + if (ret) + *set_size = 0; + return ret; +} + + +wifi_error wifi_set_nodfs_flag(wifi_interface_handle handle, u32 nodfs) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + vCommand = new WifiVendorCommand(wifiHandle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG); + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __func__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + /* Add the fixed part of the mac_oui to the nl command */ + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG, nodfs); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + /* Don't check response since we aren't expecting one */ + +cleanup: + delete vCommand; + return ret; +} + +wifi_error wifi_start_sending_offloaded_packet(wifi_request_id id, + wifi_interface_handle iface, + u16 ether_type, + u8 *ip_packet, + u16 ip_packet_len, + u8 *src_mac_addr, + u8 *dst_mac_addr, + u32 period_msec) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + + ret = initialize_vendor_cmd(iface, id, + QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __func__); + return ret; + } + + ALOGV("ether type 0x%04x\n", ether_type); + ALOGV("ip packet length : %u\nIP Packet:", ip_packet_len); + hexdump(ip_packet, ip_packet_len); + ALOGV("Src Mac Address: " MAC_ADDR_STR "\nDst Mac Address: " MAC_ADDR_STR + "\nPeriod in msec : %u", MAC_ADDR_ARRAY(src_mac_addr), + MAC_ADDR_ARRAY(dst_mac_addr), period_msec); + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_START); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_ETHER_PROTO_TYPE, + ether_type); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA, + (const char *)ip_packet, ip_packet_len); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_addr( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR, + src_mac_addr); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_addr( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR, + dst_mac_addr); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD, + period_msec); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + goto cleanup; + +cleanup: + delete vCommand; + return ret; +} + +wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + + ret = initialize_vendor_cmd(iface, id, + QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __func__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_STOP); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID, + id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + goto cleanup; + +cleanup: + delete vCommand; + return ret; +} + +#define PACKET_FILTER_ID 0 + +static wifi_error wifi_set_packet_filter(wifi_interface_handle iface, + const u8 *program, u32 len) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + u32 current_offset = 0; + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* len=0 clears the filters in driver/firmware */ + if (len != 0 && program == NULL) { + ALOGE("%s: No valid program provided. Exit.", + __func__); + return WIFI_ERROR_INVALID_ARGS; + } + + do { + ret = initialize_vendor_cmd(iface, get_requestid(), + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + QCA_WLAN_SET_PACKET_FILTER); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID, + PACKET_FILTER_ID); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + len); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + current_offset); + if (ret != WIFI_SUCCESS) + goto cleanup; + + if (len) { + ret = vCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM, + (char *)&program[current_offset], + min(info->firmware_bus_max_size, + len-current_offset)); + if (ret!= WIFI_SUCCESS) { + ALOGE("%s: failed to put program", __FUNCTION__); + goto cleanup; + } + } + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__func__, ret); + goto cleanup; + } + + /* destroy the object after sending each fragment to driver */ + delete vCommand; + vCommand = NULL; + + current_offset += min(info->firmware_bus_max_size, len); + } while (current_offset < len); + + info->apf_enabled = !!len; + +cleanup: + if (vCommand) + delete vCommand; + return ret; +} + +static wifi_error wifi_get_packet_filter_capabilities( + wifi_interface_handle handle, u32 *version, u32 *max_len) +{ + wifi_error ret; + struct nlattr *nlData; + WifihalGeneric *vCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + if (version == NULL || max_len == NULL) { + ALOGE("%s: NULL version/max_len pointer provided. Exit.", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + vCommand = new WifihalGeneric(wifiHandle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER); + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + QCA_WLAN_GET_PACKET_FILTER); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret); + if (ret == WIFI_ERROR_NOT_SUPPORTED) { + /* Packet filtering is not supported currently, so return version + * and length as 0 + */ + ALOGI("Packet filtering is not supprted"); + *version = 0; + *max_len = 0; + ret = WIFI_SUCCESS; + } + goto cleanup; + } + + *version = vCommand->getFilterVersion(); + *max_len = vCommand->getFilterLength(); +cleanup: + delete vCommand; + return ret; +} + + +static wifi_error wifi_configure_nd_offload(wifi_interface_handle iface, + u8 enable) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + + ret = initialize_vendor_cmd(iface, get_requestid(), + QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __func__); + return ret; + } + + ALOGV("ND offload : %s", enable?"Enable":"Disable"); + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u8(QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG, enable); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + +cleanup: + delete vCommand; + return ret; +} + +/** + * Copy 'len' bytes of raw data from host memory at source address 'program' + * to APF (Android Packet Filter) working memory starting at offset 'dst_offset'. + * The size of the program lenght passed to the interpreter is set to + * 'progaram_lenght' + * + * The implementation is allowed to tranlate this wrtie into a series of smaller + * writes,but this function is not allowed to return untill all write operations + * have been completed + * additionally visible memory not targeted by this function must remain + * unchanged + + * @param dst_offset write offset in bytes relative to the beginning of the APF + * working memory with logical address 0X000. Must be a multiple of 4 + * + * @param program host memory to copy bytes from. Must be 4B aligned + * + * @param len the number of bytes to copy from the bost into the APF working + * memory + * + * @param program_length new length of the program instructions in bytes to pass + * to the interpreter + */ + +wifi_error wifi_write_packet_filter(wifi_interface_handle iface, + u32 dst_offset, const u8 *program, + u32 len, u32 program_length) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + u32 current_offset = 0; + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* len=0 clears the filters in driver/firmware */ + if (len != 0 && program == NULL) { + ALOGE("%s: No valid program provided. Exit.", + __func__); + return WIFI_ERROR_INVALID_ARGS; + } + + do { + ret = initialize_vendor_cmd(iface, get_requestid(), + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER, + &vCommand); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __FUNCTION__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + QCA_WLAN_WRITE_PACKET_FILTER); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID, + PACKET_FILTER_ID); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + len); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + dst_offset + current_offset); + if (ret != WIFI_SUCCESS) + goto cleanup; + ret = vCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH, + program_length); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->put_bytes( + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM, + (char *)&program[current_offset], + min(info->firmware_bus_max_size, + len - current_offset)); + if (ret!= WIFI_SUCCESS) { + ALOGE("%s: failed to put program", __FUNCTION__); + goto cleanup; + } + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__func__, ret); + goto cleanup; + } + + /* destroy the object after sending each fragment to driver */ + delete vCommand; + vCommand = NULL; + + current_offset += min(info->firmware_bus_max_size, + len - current_offset); + } while (current_offset < len); + +cleanup: + if (vCommand) + delete vCommand; + return ret; +} + +wifi_error wifi_enable_packet_filter(wifi_interface_handle handle, + u32 enable) +{ + wifi_error ret; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + u32 subcmd; + wifi_handle wifiHandle = getWifiHandle(handle); + hal_info *info = getHalInfo(wifiHandle); + + ret = initialize_vendor_cmd(handle, get_requestid(), + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER, + &vCommand); + + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __func__); + return ret; + } + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + subcmd = enable ? QCA_WLAN_ENABLE_PACKET_FILTER : + QCA_WLAN_DISABLE_PACKET_FILTER; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + subcmd); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + ret = vCommand->requestResponse(); + + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret); + goto cleanup; + } + + info->apf_enabled = !!enable; + +cleanup: + delete vCommand; + return ret; + +} + +/** + * Copy 'length' bytes of raw data from APF (Android Packet Filter) working + * memory to host memory starting at offset src_offset into host memory + * pointed to by host_dst. + * Memory can be text, data or some combination of the two. The implementiion is + * allowed to translate this read into a series of smaller reads, but this + * function is not allowed to return untill all the reads operations + * into host_dst have been completed. + * + * @param src_offset offset in bytes of destination memory within APF working + * memory + * + * @param host_dst host memory to copy into. Must be 4B aligned. + * + * @param length the number of bytes to copy from the APF working memory to the + * host. + */ + +static wifi_error wifi_read_packet_filter(wifi_interface_handle handle, + u32 src_offset, u8 *host_dst, u32 length) +{ + wifi_error ret = WIFI_SUCCESS; + struct nlattr *nlData; + WifihalGeneric *vCommand = NULL; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + hal_info *info = getHalInfo(wifiHandle); + + /* Length to be passed to this function should be non-zero + * Return invalid argument if length is passed as zero + */ + if (length == 0) + return WIFI_ERROR_INVALID_ARGS; + + /*Temporary varibles to support the read complete length in chunks */ + u8 *temp_host_dst; + u32 remainingLengthToBeRead, currentLength; + u8 apf_locally_disabled = 0; + + /*Initializing the temporary variables*/ + temp_host_dst = host_dst; + remainingLengthToBeRead = length; + + if (info->apf_enabled) { + /* Disable APF only when not disabled by framework before calling + * wifi_read_packet_filter() + */ + ret = wifi_enable_packet_filter(handle, 0); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Failed to disable APF", __FUNCTION__); + return ret; + } + apf_locally_disabled = 1; + } + /** + * Read the complete length in chunks of size less or equal to firmware bus + * max size + */ + while (remainingLengthToBeRead) + { + vCommand = new WifihalGeneric(wifiHandle, 0, OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER); + + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __FUNCTION__); + ret = WIFI_ERROR_OUT_OF_MEMORY; + break; + } + + /* Create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + break; + ret = vCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + break; + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + break; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + QCA_WLAN_READ_PACKET_FILTER); + if (ret != WIFI_SUCCESS) + break; + + currentLength = min(remainingLengthToBeRead, info->firmware_bus_max_size); + + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + currentLength); + if (ret != WIFI_SUCCESS) + break; + ret = vCommand->put_u32(QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + src_offset); + if (ret != WIFI_SUCCESS) + break; + + vCommand->setPacketBufferParams(temp_host_dst, currentLength); + vCommand->attr_end(nlData); + ret = vCommand->requestResponse(); + + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse() error: %d current_len = %u, src_offset = %u", + __FUNCTION__, ret, currentLength, src_offset); + break; + } + + remainingLengthToBeRead -= currentLength; + temp_host_dst += currentLength; + src_offset += currentLength; + delete vCommand; + vCommand = NULL; + } + + /* Re enable APF only when disabled above within this API */ + if (apf_locally_disabled) { + wifi_error status; + status = wifi_enable_packet_filter(handle, 1); + if (status != WIFI_SUCCESS) + ALOGE("%s: Failed to enable APF", __FUNCTION__); + /* Prefer to return read status if read fails */ + if (ret == WIFI_SUCCESS) + ret = status; + } + + delete vCommand; + return ret; +} + +class GetSupportedVendorCmd : public WifiCommand +{ +private: + u32 mVendorCmds[256]; + int mNumOfVendorCmds; + +public: + GetSupportedVendorCmd(wifi_handle handle) : WifiCommand(handle, 0) + { + mNumOfVendorCmds = 0; + memset(mVendorCmds, 0, 256); + } + + virtual wifi_error create() { + int nl80211_id = genl_ctrl_resolve(mInfo->cmd_sock, "nl80211"); + wifi_error ret = mMsg.create(nl80211_id, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, 0); + mMsg.put_flag(NL80211_ATTR_SPLIT_WIPHY_DUMP); + + return ret; + } + + virtual wifi_error requestResponse() { + return WifiCommand::requestResponse(mMsg); + } + virtual wifi_error set_iface_id(const char* name) { + unsigned ifindex = if_nametoindex(name); + return mMsg.set_iface_id(ifindex); + } + + virtual int handleResponse(WifiEvent& reply) { + struct nlattr **tb = reply.attributes(); + + if (tb[NL80211_ATTR_VENDOR_DATA]) { + struct nlattr *nl; + int rem, i = 0; + + for_each_attr(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) { + struct nl80211_vendor_cmd_info *vinfo; + if (nla_len(nl) != sizeof(*vinfo)) { + ALOGE("Unexpected vendor data info found in attribute"); + continue; + } + vinfo = (struct nl80211_vendor_cmd_info *)nla_data(nl); + if (vinfo->vendor_id == OUI_QCA) { + mVendorCmds[i] = vinfo->subcmd; + i++; + } + } + mNumOfVendorCmds = i; + } + return NL_SKIP; + } + + int isVendorCmdSupported(u32 cmdId) { + int i, ret; + + ret = 0; + for (i = 0; i < mNumOfVendorCmds; i++) { + if (cmdId == mVendorCmds[i]) { + ret = 1; + break; + } + } + + return ret; + } +}; + +static int wifi_is_nan_ext_cmd_supported(wifi_interface_handle iface_handle) +{ + wifi_error ret; + wifi_handle handle = getWifiHandle(iface_handle); + interface_info *info = getIfaceInfo(iface_handle); + GetSupportedVendorCmd cmd(handle); + + ret = cmd.create(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: create command failed", __func__); + return 0; + } + + ret = cmd.set_iface_id(info->name); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: set iface id failed", __func__); + return 0; + } + + ret = cmd.requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to query nan_ext command support, ret=%d", ret); + return 0; + } else { + return cmd.isVendorCmdSupported(QCA_NL80211_VENDOR_SUBCMD_NAN_EXT); + } +} + +static u32 get_nl_band_mask(u32 in_mask) +{ + u32 op_mask = 0; + + if (in_mask & WLAN_MAC_2_4_BAND) + op_mask |= BIT(NL80211_BAND_2GHZ); + if (in_mask & WLAN_MAC_5_0_BAND) + op_mask |= BIT(NL80211_BAND_5GHZ); + if (in_mask & WLAN_MAC_6_0_BAND) + op_mask |= BIT(NL80211_BAND_6GHZ); + if (in_mask & WLAN_MAC_60_0_BAND) + op_mask |= BIT(NL80211_BAND_60GHZ); + + return op_mask; +} + +static u32 get_nl_iftype_mode_masks(u32 in_mask) +{ + u32 op_mask = 0; + + if (in_mask & BIT(WIFI_INTERFACE_STA) || + in_mask & BIT(WIFI_INTERFACE_TDLS)) + op_mask |= BIT(NL80211_IFTYPE_STATION); + if (in_mask & BIT(WIFI_INTERFACE_SOFTAP)) + op_mask |= BIT(NL80211_IFTYPE_AP); + if (in_mask & BIT(WIFI_INTERFACE_P2P_CLIENT)) + op_mask |= BIT(NL80211_IFTYPE_P2P_CLIENT); + if (in_mask & BIT(WIFI_INTERFACE_P2P_GO)) + op_mask |= BIT(NL80211_IFTYPE_P2P_GO); + if (in_mask & BIT(WIFI_INTERFACE_NAN)) + op_mask |= BIT(NL80211_IFTYPE_NAN); + + return op_mask; +} + +static u32 get_vendor_filter_mask(u32 in_mask) +{ + u32 op_mask = 0; + + if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE) + op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX); + if (in_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY) + op_mask |= BIT(QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY); + + return op_mask; +} + +wifi_error wifi_get_usable_channels(wifi_handle handle, u32 band_mask, + u32 iface_mode_mask, u32 filter_mask, + u32 max_size, u32* size, + wifi_usable_channel* channels) +{ + wifi_error ret; + WifihalGeneric *cmd = NULL; + struct nlattr *nl_data; + hal_info *info = NULL; + u32 band = 0, iface_mask = 0, filter = 0; + + if (!handle) { + ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + info = getHalInfo(handle); + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error, wifi_handle NULL or base wlan interface not present", + __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + if (!max_size) { + ALOGE("%s: max channel size is zero", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + + if (!channels) { + ALOGE("%s: user input channel buffer NULL", __FUNCTION__); + ret = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + + cmd = new WifihalGeneric(handle, get_requestid(), OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS); + if (cmd == NULL) { + ALOGE("%s: Error, created command NULL", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the NL message. */ + ret = cmd->create(); + if (ret < 0) { + ALOGE("%s: failed to create NL msg due to error: (%d)", + __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nl_data = cmd->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) { + ALOGE("%s: failed attr_start for VENDOR_DATA due to error: (%d)", + __FUNCTION__, ret); + goto cleanup; + } + + band = get_nl_band_mask(band_mask); + ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK, + band); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to put vendor data due to error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + iface_mask = get_nl_iftype_mode_masks(iface_mode_mask); + ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK, + iface_mask); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to put vendor data due to error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + filter = get_vendor_filter_mask(filter_mask); + ret = cmd->put_u32(QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK, + filter); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: failed to put vendor data due to error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + cmd->attr_end(nl_data); + + /* Populate the input received from caller/framework. */ + cmd->setMaxSetSize(max_size); + cmd->set_channels_buff(channels); + + /* Send the msg and wait for a response. */ + ret = cmd->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Error %d waiting for response.", __FUNCTION__, ret); + goto cleanup; + } + + *size = cmd->get_results_size(); + +cleanup: + delete cmd; + return ret; +} + +wifi_error wifi_get_radar_history(wifi_interface_handle handle, + radar_history_result *resultBuf, int resultBufSize, int *numResults) +{ + wifi_error ret; + struct nlattr *nlData; + WifihalGeneric *vCommand = NULL; + interface_info *ifaceInfo = NULL; + wifi_handle wifiHandle = NULL; + + ALOGI("%s: enter", __FUNCTION__); + + if (!handle) { + ALOGE("%s: Error, wifi_interface_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ifaceInfo = getIfaceInfo(handle); + if (!ifaceInfo) { + ALOGE("%s: Error, interface_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + wifiHandle = getWifiHandle(handle); + if (!wifiHandle) { + ALOGE("%s: Error, wifi_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + if (resultBuf == NULL || numResults == NULL) { + ALOGE("%s: Error, resultsBuf/numResults NULL pointer", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + vCommand = new WifihalGeneric(wifiHandle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY); + if (vCommand == NULL) { + ALOGE("%s: Error vCommand NULL", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Create the message */ + ret = vCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = vCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + vCommand->attr_end(nlData); + + ret = vCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret); + goto cleanup; + } + + /* No more data, copy the parsed results into the caller's results buffer */ + ret = vCommand->copyCachedRadarHistory( + resultBuf, resultBufSize, numResults); + +cleanup: + vCommand->freeCachedRadarHistory(); + delete vCommand; + return ret; +} + +#define SIZEOF_TLV_HDR 4 +#define OEM_DATA_TLV_TYPE_HEADER 1 +#define OEM_DATA_CMD_SET_SKIP_CAC 18 + +struct oem_data_header { + u16 cmd_id; + u16 request_idx; +}; + +static int wifi_add_oem_data_head(int cmd_id, u8* oem_buf, size_t max) +{ + struct oem_data_header oem_hdr; + oem_hdr.cmd_id = cmd_id; + oem_hdr.request_idx = 0; + + if ((SIZEOF_TLV_HDR + sizeof(oem_hdr)) > max) { + return 0; + } + + wifi_put_le16(oem_buf, OEM_DATA_TLV_TYPE_HEADER); + oem_buf += 2; + wifi_put_le16(oem_buf, sizeof(oem_hdr)); + oem_buf += 2; + memcpy(oem_buf, (u8 *)&oem_hdr, sizeof(oem_hdr)); + oem_buf += sizeof(oem_hdr); + + return (SIZEOF_TLV_HDR + sizeof(oem_hdr)); +} + + +/** + * This cmd takes effect on the interface the cmd is sent to. + * This cmd loses effect when interface is down. (i.e. set mac addr) + */ +wifi_error wifi_disable_next_cac(wifi_interface_handle handle) { + wifi_error ret; + interface_info *ifaceInfo = NULL; + struct nlattr *nlData; + WifiVendorCommand *vCommand = NULL; + u8 oem_buf[16]; + int oem_buf_len = 0; + + if (!handle) { + ALOGE("%s: Error, wifi_interface_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ifaceInfo = getIfaceInfo(handle); + if (!ifaceInfo) { + ALOGE("%s: Error, interface_info NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ALOGI("%s: enter - iface=%s", __FUNCTION__, ifaceInfo->name); + oem_buf_len = wifi_add_oem_data_head( + OEM_DATA_CMD_SET_SKIP_CAC, oem_buf, sizeof(oem_buf)); + if (oem_buf_len <= 0) { + ALOGE("%s: fill oem data head failed, cmd=%d", __func__, + OEM_DATA_CMD_SET_SKIP_CAC); + return WIFI_ERROR_UNKNOWN; + } + + ret = initialize_vendor_cmd(handle, get_requestid(), + QCA_NL80211_VENDOR_SUBCMD_OEM_DATA, + &vCommand); + + if (ret != WIFI_SUCCESS) { + ALOGE("%s: Initialization failed", __func__); + return ret; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = vCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ret = WIFI_ERROR_OUT_OF_MEMORY; + goto cleanup; + } + + ret = vCommand->put_bytes(QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA, + (char *)oem_buf, oem_buf_len); + if (ret != WIFI_SUCCESS) + goto cleanup; + + vCommand->attr_end(nlData); + ret = vCommand->requestResponse(); + + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse() error: %d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + delete vCommand; + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c new file mode 100644 index 0000000..ddc0062 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * wpa_supplicant/hostapd control interface library + * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> + * + * This software may be distributed under the terms of the BSD license. + * 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. Neither the name(s) of the above-listed copyright holder(s) 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 AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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. + */ + +#include "wifi_hal_ctrl.h" + +struct wifihal_ctrl * wifihal_ctrl_open2(const char *ctrl_path, + const char *cli_path) +{ + struct wifihal_ctrl *ctrl; + static int counter = 0; + int retval; + size_t res; + int tries = 0; + int flags; +#ifdef ANDROID + struct group *grp_wifi; + gid_t gid_wifi; + struct passwd *pwd_system; + uid_t uid_system; +#endif + + if (ctrl_path == NULL) + return NULL; + + ctrl = malloc(sizeof(*ctrl)); + if (ctrl == NULL) { + return NULL; + } + + memset(ctrl, 0, sizeof(*ctrl)); + ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0); + if (ctrl->s < 0) { + free(ctrl); + return NULL; + } + + ctrl->local.sun_family = AF_UNIX; + +try_again: + if (cli_path && cli_path[0] == '/') { + res = strlcpy(ctrl->local.sun_path, cli_path, + sizeof(ctrl->local.sun_path)); + + if (res >= sizeof(ctrl->local.sun_path)) { + close(ctrl->s); + free(ctrl); + return NULL; + } + + } else { + counter++; + retval = snprintf(ctrl->local.sun_path, + sizeof(ctrl->local.sun_path), + CONFIG_CTRL_IFACE_CLIENT_DIR "/" + CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d", + (int) getpid(), counter); + } + tries++; + if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, + sizeof(ctrl->local)) < 0) { + if (errno == EADDRINUSE && tries < 2) { + /* + * getpid() returns unique identifier for this instance + * of wifihal_ctrl, so the existing socket file must have + * been left by unclean termination of an earlier run. + * Remove the file and try again. + */ + unlink(ctrl->local.sun_path); + goto try_again; + } + close(ctrl->s); + free(ctrl); + return NULL; + } + +#ifdef ANDROID + chmod(ctrl->local.sun_path, S_IRWXU | S_IRWXG ); + + /* Set group even if we do not have privileges to change owner */ + grp_wifi = getgrnam("wifi"); + gid_wifi = grp_wifi ? grp_wifi->gr_gid : 0; + pwd_system = getpwnam("system"); + uid_system = pwd_system ? pwd_system->pw_uid : 0; + if (!gid_wifi || !uid_system) { + close(ctrl->s); + unlink(ctrl->local.sun_path); + free(ctrl); + return NULL; + } + chown(ctrl->local.sun_path, -1, gid_wifi); + chown(ctrl->local.sun_path, uid_system, gid_wifi); + + + if (*ctrl_path != '/') { + free(ctrl); + return NULL; + } +#endif /* ANDROID */ + + ctrl->dest.sun_family = AF_UNIX; + res = strlcpy(ctrl->dest.sun_path, ctrl_path, + sizeof(ctrl->dest.sun_path)); + if (res >= sizeof(ctrl->dest.sun_path)) { + close(ctrl->s); + free(ctrl); + return NULL; + } + if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, + sizeof(ctrl->dest)) < 0) { + close(ctrl->s); + unlink(ctrl->local.sun_path); + free(ctrl); + return NULL; + } + /* + * Make socket non-blocking so that we don't hang forever if + * target dies unexpectedly. + */ + flags = fcntl(ctrl->s, F_GETFL); + if (flags >= 0) { + flags |= O_NONBLOCK; + if (fcntl(ctrl->s, F_SETFL, flags) < 0) { + perror("fcntl(ctrl->s, O_NONBLOCK)"); + /* Not fatal, continue on.*/ + } + } + return ctrl; +} + +struct wifihal_ctrl * wifihal_ctrl_open(const char *ctrl_path) +{ + return wifihal_ctrl_open2(ctrl_path, NULL); +} + +void wifihal_ctrl_close(struct wifihal_ctrl *ctrl) +{ + if (ctrl == NULL) + return; + unlink(ctrl->local.sun_path); + if (ctrl->s >= 0) + close(ctrl->s); + free(ctrl); +} + +int wifihal_ctrl_request2(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len, time_t sec, suseconds_t usec) +{ + struct timeval tv; + int counter = 0, res; + fd_set rfds; + const char *_cmd; + size_t _cmd_len; + char *cmd_buf = NULL; + + _cmd = cmd; + _cmd_len = cmd_len; + + errno = 0; +retry_send: + if (sendto(ctrl->s, _cmd, _cmd_len, 0, (struct sockaddr *)&ctrl->dest, sizeof(ctrl->dest)) < 0) { + if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK) + { + /* + * Must be a non-blocking socket... Try for a bit + * longer before giving up. + */ + if(counter == 5) { + goto send_err; + } else { + counter++; + } + sleep(1); + goto retry_send; + } + send_err: + free(cmd_buf); + return -1; + } + free(cmd_buf); + + for (;;) { + tv.tv_sec = sec; + tv.tv_usec = usec; + FD_ZERO(&rfds); + FD_SET(ctrl->s, &rfds); + res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv); + if (res < 0 && errno == EINTR) + continue; + if (res < 0) + return res; + if (FD_ISSET(ctrl->s, &rfds)) { + res = recv(ctrl->s, reply, *reply_len, 0); + if (res < 0) + return res; + *reply_len = res; + break; + } else { + return -2; + } + } + return 0; +} + + +int wifihal_ctrl_request(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len) +{ + return wifihal_ctrl_request2(ctrl, cmd, cmd_len, reply, reply_len, 1, 0); +} diff --git a/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h new file mode 100644 index 0000000..f0cdaa3 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + * + * wpa_supplicant/hostapd control interface library + * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> + * + * This software may be distributed under the terms of the BSD license. + * 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. Neither the name(s) of the above-listed copyright holder(s) 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 AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER 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. + */ + +#ifndef WIFIHAL_CTRL_H +#define WIFIHAL_CTRL_H + +#include <sys/un.h> +#include <unistd.h> +#include <fcntl.h> + +#include "stdlib.h" + +#ifdef ANDROID +#include <dirent.h> +#include <grp.h> +#include <pwd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <cutils/sockets.h> +#endif /* ANDROID */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * struct wifihal_ctrl - Internal structure for control interface library + * + * This structure is used by the clients to interface with WiFi Hal + * library to store internal data. Programs using the library should not touch + * this data directly. They can only use the pointer to the data structure as + * an identifier for the control interface connection and use this as one of + * the arguments for most of the control interface library functions. + */ + +struct wifihal_ctrl { + int s; + struct sockaddr_un local; + struct sockaddr_un dest; +}; + +#ifndef CONFIG_CTRL_IFACE_CLIENT_DIR +#define CONFIG_CTRL_IFACE_CLIENT_DIR "/dev/socket/wifihal" +#endif /* CONFIG_CTRL_IFACE_CLIENT_DIR */ +#ifndef CONFIG_CTRL_IFACE_CLIENT_PREFIX +#define CONFIG_CTRL_IFACE_CLIENT_PREFIX "wifihal_ctrl_cli_" +#endif /* CONFIG_CTRL_IFACE_CLIENT_PREFIX */ + +#define DEFAULT_PAGE_SIZE 4096 + +enum nl_family_type +{ + //! gen netlink family + GENERIC_NL_FAMILY = 1, + //! Cld80211 family + CLD80211_FAMILY +}; + + +enum wifihal_ctrl_cmd +{ + /** attach monitor sock */ + WIFIHAL_CTRL_MONITOR_ATTACH, + /** dettach monitor sock */ + WIFIHAL_CTRL_MONITOR_DETTACH, + /** Send data over Netlink Sock */ + WIFIHAL_CTRL_SEND_NL_DATA, +}; + +//! WIFIHAL Control Request +typedef struct wifihal_ctrl_req_s { + //! ctrl command + uint32_t ctrl_cmd; + //! Family name + uint32_t family_name; + //! command ID + uint32_t cmd_id; + //! monitor sock len + uint32_t monsock_len; + //! monitor sock + struct sockaddr_un monsock; + //! data buff length + uint32_t data_len; + //! reserved + uint32_t reserved[4]; + //! data + char data[0]; +}wifihal_ctrl_req_t; + + +//! WIFIHAL Sync Response +typedef struct wifihal_ctrl_sync_rsp_s { + //! ctrl command + uint32_t ctrl_cmd; + //! Family name + uint32_t family_name; + //! command ID + uint32_t cmd_id; + //! status for the request + int status; + //! reserved + uint32_t reserved[4]; +}wifihal_ctrl_sync_rsp_t; + +//! WIFIHAL Async Response +typedef struct wifihal_ctrl_event_s { + //! Family name + uint32_t family_name; + //! command ID + uint32_t cmd_id; + //! data buff length + uint32_t data_len; + //! reserved + uint32_t reserved; + //! data + char data[0]; +}wifihal_ctrl_event_t; + +/* WiFi Hal control interface access */ + +/** + * wifihal_ctrl_open - Open a control interface to WiFi-Hal + * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used. + * Returns: Pointer to abstract control interface data or %NULL on failure + * + * This function is used to open a control interface to WiFi-Hal. + * ctrl_path is usually /var/run/wifihal. This path + * is configured in WiFi-Hal and other programs using the control + * interface need to use matching path configuration. + */ +struct wifihal_ctrl * wifihal_ctrl_open(const char *ctrl_path); + +/** + * wifihal_ctrl_open2 - Open a control interface to wifihal + * @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used. + * @cli_path: Path for client UNIX domain sockets; ignored if UDP socket + * is used. + * Returns: Pointer to abstract control interface data or %NULL on failure + * + * This function is used to open a control interface to wifihal + * when the socket path for client need to be specified explicitly. Default + * ctrl_path is usually /var/run/wifihal and client + * socket path is /tmp. + */ +struct wifihal_ctrl * wifihal_ctrl_open2(const char *ctrl_path, const char *cli_path); + + +/** + * wifihal_ctrl_close - Close a control interface to wifihal + * @ctrl: Control interface data from wifihal_ctrl_open() + * + * This function is used to close a control interface. + */ +void wifihal_ctrl_close(struct wifihal_ctrl *ctrl); + + +/** + * wifihal_ctrl_request2 - Send a command to wifihal + * @ctrl: Control interface data from wifihal_ctrl_open() + * @cmd: Command; usually, hexadecimal data + * @cmd_len: Length of the cmd in bytes + * @reply: Buffer for the response + * @reply_len: Reply buffer length + * @sec: time in secs + * @usec: time in micro secs + * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout + * + * This function is used to send commands to wifihal. Received + * response will be written to reply and reply_len is set to the actual length + * of the reply. This function will block for up to two seconds while waiting + * for the reply. If unsolicited messages are received, the blocking time may + * be longer. + * + */ +int wifihal_ctrl_request2(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len, time_t sec, suseconds_t usec); + +/** + * wifihal_ctrl_request - Send a command to wifihal + * @ctrl: Control interface data from wifihal_ctrl_open() + * @cmd: Command; usually, hexadecimal data + * @cmd_len: Length of the cmd in bytes + * @reply: Buffer for the response + * @reply_len: Reply buffer length + * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout + * + * This function is used to send commands to wifihal. Received + * response will be written to reply and reply_len is set to the actual length + * of the reply. This function will block for up to two seconds while waiting + * for the reply. If unsolicited messages are received, the blocking time may + * be longer. + * + */ +int wifihal_ctrl_request(struct wifihal_ctrl *ctrl, const char *cmd, size_t cmd_len, + char *reply, size_t *reply_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wcn6740/qcwcn/wifi_hal/wificonfig.cpp b/wcn6740/qcwcn/wifi_hal/wificonfig.cpp new file mode 100644 index 0000000..a3b4bfb --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wificonfig.cpp @@ -0,0 +1,1228 @@ +/* Copyright (c) 2015, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" +#define LOG_TAG "WifiHAL" +#include <utils/Log.h> +#include <time.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <string> +#include <net/if.h> +#include <vector> +#include <sys/ioctl.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <sys/socket.h> +#include "wificonfigcommand.h" + +/* Implementation of the API functions exposed in wifi_config.h */ +wifi_error wifi_extended_dtim_config_set(wifi_request_id id, + wifi_interface_handle iface, + int extended_dtim) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + ALOGV("%s: extended_dtim:%d", __FUNCTION__, extended_dtim); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_extended_dtim_config_set: failed to create NL msg. " + "Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_extended_dtim_config_set: failed to set iface id. " + "Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_extended_dtim_config_set: failed attr_start for " + "VENDOR_DATA. Error:%d", ret); + goto cleanup; + } + + ret = wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM, extended_dtim); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_extended_dtim_config_set(): failed to put vendor data. " + "Error:%d", ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_extended_dtim_config_set(): requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +int check_feature(enum qca_wlan_vendor_features feature, features_info *info) +{ + size_t idx = feature / 8; + + return (idx < info->flags_len) && + (info->flags[idx] & BIT(feature % 8)); +} + +/* Set the country code to driver. */ +wifi_error wifi_set_country_code(wifi_interface_handle iface, + const char* country_code) +{ + int requestId; + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + ALOGV("%s: %s", __FUNCTION__, country_code); + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate it randomly. + */ + requestId = get_requestid(); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message with NL80211_CMD_REQ_SET_REG NL cmd. */ + ret = wifiConfigCommand->create_generic(NL80211_CMD_REQ_SET_REG); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_country_code: failed to create NL msg. Error:%d", ret); + goto cleanup; + } + + ret = wifiConfigCommand->put_string(NL80211_ATTR_REG_ALPHA2, country_code); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_country_code: put country code failed. Error:%d", ret); + goto cleanup; + } + + if (check_feature(QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY, + &info->driver_supported_features)) { + ret = wifiConfigCommand->put_u32(NL80211_ATTR_USER_REG_HINT_TYPE, + NL80211_USER_REG_HINT_CELL_BASE); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_country_code: put reg hint type failed. Error:%d", + ret); + goto cleanup; + } + } + + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_country_code(): requestEvent Error:%d", ret); + goto cleanup; + } + usleep(WAIT_TIME_FOR_SET_REG_DOMAIN); + +cleanup: + delete wifiConfigCommand; + return ret; +} + +/* + * Set the powersave to driver. + */ +wifi_error wifi_set_qpower(wifi_interface_handle iface, + u8 powersave) +{ + int requestId, ret = 0; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + //hal_info *info = getHalInfo(wifiHandle); + + ALOGD("%s: %d", __FUNCTION__, powersave); + + requestId = get_requestid(); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret < 0) { + ALOGE("wifi_set_qpower: failed to create NL msg. " + "Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret < 0) { + ALOGE("wifi_set_qpower: failed to set iface id. " + "Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_set_qpower: failed attr_start for " + "VENDOR_DATA. Error:%d", ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER, powersave)) { + ALOGE("wifi_set_qpower(): failed to put vendor data. " + "Error:%d", ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != 0) { + ALOGE("wifi_set_qpower(): requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return (wifi_error)ret; + +} + +wifi_error wifi_set_beacon_wifi_iface_stats_averaging_factor( + wifi_request_id id, + wifi_interface_handle iface, + u16 factor) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + ALOGV("%s factor:%u", __FUNCTION__, factor); + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to " + "create NL msg. Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed to " + "set iface id. Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor: failed " + "attr_start for VENDOR_DATA. Error:%d", ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR, factor)) { + ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): failed to " + "put vendor data. Error:%d", ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_beacon_wifi_iface_stats_averaging_factor(): " + "requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_set_guard_time(wifi_request_id id, + wifi_interface_handle iface, + u32 guard_time) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + ALOGV("%s : guard_time:%u", __FUNCTION__, guard_time); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + id, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_guard_time: failed to create NL msg. Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_guard_time: failed to set iface id. Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_set_guard_time: failed attr_start for VENDOR_DATA. " + "Error:%d", ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME, guard_time)) { + ALOGE("wifi_set_guard_time: failed to add vendor data."); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_set_guard_time(): requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle, + wifi_power_scenario scenario) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + u32 bdf_file = 0; + + ALOGV("%s : power scenario:%d", __FUNCTION__, scenario); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + 1, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_select_tx_power_scenario: failed to create NL msg. Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_select_tx_power_scenario: failed to set iface id. Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_select_tx_power_scenario: failed attr_start for VENDOR_DATA. " + "Error:%d", ret); + goto cleanup; + } + + switch (scenario) { + case WIFI_POWER_SCENARIO_VOICE_CALL: + case WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF: + bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0; + break; + + case WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON: + bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1; + break; + + case WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF: + bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2; + break; + + case WIFI_POWER_SCENARIO_ON_BODY_CELL_ON: + bdf_file = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3; + break; + + default: + ALOGE("wifi_select_tx_power_scenario: invalid scenario %d", scenario); + ret = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE, + bdf_file)) { + ALOGE("failed to put SAR_ENABLE"); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_select_tx_power_scenario(): requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(handle); + wifi_handle wifiHandle = getWifiHandle(handle); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + 1, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_reset_tx_power_scenario: failed to create NL msg. Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_reset_tx_power_scenario: failed to set iface id. Error:%d", ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("wifi_reset_tx_power_scenario: failed attr_start for VENDOR_DATA. " + "Error:%d", ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE)) { + ALOGE("failed to put SAR_ENABLE or NUM_SPECS"); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("wifi_reset_tx_power_scenario(): requestEvent Error:%d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_set_thermal_mitigation_mode(wifi_handle handle, + wifi_thermal_mode mode, + u32 completion_window) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + u32 qca_vendor_thermal_level; + hal_info *info = getHalInfo(handle); + + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", + __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + wifiConfigCommand = new WiFiConfigCommand( + handle, + 1, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error, Failed to create wifiConfigCommand", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to create thermal vendor command, Error:%d", ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, + info->interfaces[0]->id)) { + ALOGE("%s: Failed to put iface id", __FUNCTION__); + goto cleanup; + } + + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: Failed in attr_start for VENDOR_DATA, Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u32(QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL)) { + ALOGE("Failed to put THERMAL_LEVEL command type"); + goto cleanup; + } + + switch(mode) { + case WIFI_MITIGATION_NONE: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE; + break; + case WIFI_MITIGATION_LIGHT: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT; + break; + case WIFI_MITIGATION_MODERATE: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE; + break; + case WIFI_MITIGATION_SEVERE: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE; + break; + case WIFI_MITIGATION_CRITICAL: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL; + break; + case WIFI_MITIGATION_EMERGENCY: + qca_vendor_thermal_level = QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY; + break; + default: + ALOGE("Unknown thermal mitigation level %d", mode); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL, + qca_vendor_thermal_level)) { + ALOGE("Failed to put thermal level"); + goto cleanup; + } + + if (wifiConfigCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW, + completion_window)) { + ALOGE("Failed to put thermal completion window"); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to set thermal level with Error: %d", ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return ret; +} + +WiFiConfigCommand::WiFiConfigCommand(wifi_handle handle, + int id, u32 vendor_id, + u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + /* Initialize the member data variables here */ + mWaitforRsp = false; + mRequestId = id; +} + +WiFiConfigCommand::~WiFiConfigCommand() +{ + unregisterVendorHandler(mVendor_id, mSubcmd); +} + +/* This function implements creation of Vendor command */ +wifi_error WiFiConfigCommand::create() +{ + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + return ret; + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + + return ret; +} + +/* This function implements creation of generic NL command */ +wifi_error WiFiConfigCommand::create_generic(u8 cmdId) +{ + wifi_error ret = mMsg.create(cmdId, 0, 0); + return ret; +} + +void WiFiConfigCommand::waitForRsp(bool wait) +{ + mWaitforRsp = wait; +} + +/* Callback handlers registered for nl message send */ +static int error_handler_wifi_config(struct sockaddr_nl *nla, + struct nlmsgerr *err, + void *arg) +{ + struct sockaddr_nl *tmp; + int *ret = (int *)arg; + tmp = nla; + *ret = err->error; + ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret))); + return NL_STOP; +} + +/* Callback handlers registered for nl message send */ +static int ack_handler_wifi_config(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + a = msg; + *ret = 0; + return NL_STOP; +} + +/* Callback handlers registered for nl message send */ +static int finish_handler_wifi_config(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + a = msg; + *ret = 0; + return NL_SKIP; +} + +/* + * Override base class requestEvent and implement little differently here. + * This will send the request message. + * We don't wait for any response back in case of wificonfig, + * thus no wait for condition. + */ +wifi_error WiFiConfigCommand::requestEvent() +{ + int status; + wifi_error res = WIFI_SUCCESS; + struct nl_cb *cb = NULL; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + ALOGE("%s: Callback allocation failed",__FUNCTION__); + res = WIFI_ERROR_OUT_OF_MEMORY; + goto out; + } + + status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + status = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_config, &status); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_config, + &status); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_config, &status); + + /* Err is populated as part of finish_handler. */ + while (status > 0) { + nl_recvmsgs(mInfo->cmd_sock, cb); + } + + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + + if (mWaitforRsp == true) { + struct timespec abstime; + abstime.tv_sec = 4; + abstime.tv_nsec = 0; + res = mCondition.wait(abstime); + if (res == WIFI_ERROR_TIMED_OUT) + ALOGE("%s: Time out happened.", __FUNCTION__); + + ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d", + __FUNCTION__, res, mWaitforRsp); + } +out: + nl_cb_put(cb); + /* Cleanup the mMsg */ + mMsg.destroy(); + return res; +} + + + +static std::vector<std::string> added_ifaces; + +static bool is_dynamic_interface(const char * ifname) +{ + for (const auto& iface : added_ifaces) { + if (iface == std::string(ifname)) + return true; + } + return false; +} + +void wifi_cleanup_dynamic_ifaces(wifi_handle handle) +{ + int len = added_ifaces.size(); + while (len--) { + wifi_virtual_interface_delete(handle, added_ifaces.front().c_str()); + } + added_ifaces.clear(); // could be redundent. But to be on safe side. +} + +static wifi_error wifi_set_interface_mode(wifi_handle handle, + const char* ifname, + u32 iface_type) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + + ALOGD("%s: ifname=%s iface_type=%u", __FUNCTION__, ifname, iface_type); + + wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nl80211_iftype type; + switch(iface_type) { + case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */ + type = NL80211_IFTYPE_STATION; + break; + case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */ + type = NL80211_IFTYPE_AP; + break; + case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */ + type = NL80211_IFTYPE_P2P_DEVICE; + break; + case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */ + type = NL80211_IFTYPE_NAN; + break; + default: + ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type); + ret = WIFI_ERROR_UNKNOWN; + goto done; + break; + } + wifiConfigCommand->create_generic(NL80211_CMD_SET_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname)); + wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + } + +done: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_virtual_interface_create(wifi_handle handle, + const char* ifname, + wifi_interface_type iface_type) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + hal_info *info = getHalInfo(handle); + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + // Already exists and set interface mode only + if (if_nametoindex(ifname) != 0) { + return wifi_set_interface_mode(handle, ifname, iface_type); + } + + ALOGD("%s: ifname=%s create", __FUNCTION__, ifname); + + wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + nl80211_iftype type; + switch(iface_type) { + case WIFI_INTERFACE_TYPE_STA: /* IfaceType:STA */ + type = NL80211_IFTYPE_STATION; + break; + case WIFI_INTERFACE_TYPE_AP: /* IfaceType:AP */ + type = NL80211_IFTYPE_AP; + break; + case WIFI_INTERFACE_TYPE_P2P: /* IfaceType:P2P */ + type = NL80211_IFTYPE_P2P_DEVICE; + break; + case WIFI_INTERFACE_TYPE_NAN: /* IfaceType:NAN */ + type = NL80211_IFTYPE_NAN; + break; + default: + ALOGE("%s: Wrong interface type %u", __FUNCTION__, iface_type); + ret = WIFI_ERROR_UNKNOWN; + goto done; + break; + } + wifiConfigCommand->create_generic(NL80211_CMD_NEW_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX,info->interfaces[0]->id); + wifiConfigCommand->put_string(NL80211_ATTR_IFNAME, ifname); + wifiConfigCommand->put_u32(NL80211_ATTR_IFTYPE, type); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret); + } + // Update dynamic interface list + added_ifaces.push_back(std::string(ifname)); + if (iface_type == WIFI_INTERFACE_TYPE_STA) { + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if(sock < 0) { + ALOGE("%s :socket error, Failed to bring up iface \n", __func__); + goto done; + } + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) { + ALOGE("%s :Could not read interface %s flags \n", __func__, ifname); + goto done; + } + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) { + ALOGE("%s :Could not bring iface %s up \n", __func__, ifname); + } + } + +done: + delete wifiConfigCommand; + return ret; +} + +wifi_error wifi_virtual_interface_delete(wifi_handle handle, + const char* ifname) +{ + wifi_error ret; + WiFiConfigCommand *wifiConfigCommand; + if (!handle) { + ALOGE("%s: Error wifi_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: ifname=%s delete", __FUNCTION__, ifname); + if (if_nametoindex(ifname) && !is_dynamic_interface(ifname)) { + // Do not remove interface if it was not added dynamically. + return WIFI_SUCCESS; + } + wifiConfigCommand = new WiFiConfigCommand(handle, get_requestid(), 0, 0); + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + wifiConfigCommand->create_generic(NL80211_CMD_DEL_INTERFACE); + wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, if_nametoindex(ifname)); + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__,ret); + } + // Update dynamic interface list + added_ifaces.erase(std::remove(added_ifaces.begin(), added_ifaces.end(), std::string(ifname)), + added_ifaces.end()); + + delete wifiConfigCommand; + return ret; +} + +/** + * Set latency level + */ +wifi_error wifi_set_latency_mode(wifi_interface_handle iface, + wifi_latency_mode mode) +{ + int requestId, ret = 0; + u16 level; + WiFiConfigCommand *wifiConfigCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + ALOGD("%s: %d", __FUNCTION__, mode); + + if (!(info->supported_feature_set & WIFI_FEATURE_SET_LATENCY_MODE)) { + ALOGE("%s: Latency Mode is not supported by driver", __FUNCTION__); + return WIFI_ERROR_NOT_SUPPORTED; + }; + + switch (mode) { + case WIFI_LATENCY_MODE_NORMAL: + level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + break; + case WIFI_LATENCY_MODE_LOW: + level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW; + break; + default: + ALOGI("%s: Unsupported latency mode=%d, resetting to NORMAL!", __FUNCTION__, mode); + level = QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL; + break; + } + + requestId = get_requestid(); + + wifiConfigCommand = new WiFiConfigCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret < 0) { + ALOGE("%s: failed to create NL msg. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret < 0) { + ALOGE("%s: failed to set iface id. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u16( + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL, level)) { + ALOGE("%s: failed to put vendor data. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != 0) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return (wifi_error)ret; +} + +/** + * Set STA + STA primary iface connection + */ +wifi_error wifi_multi_sta_set_primary_connection(wifi_handle handle, + wifi_interface_handle iface) +{ + int requestId, ret = 0; + WiFiConfigCommand *wifiConfigCommand; + if (!handle) { + ALOGE("%s: Error wifi_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + + requestId = get_requestid(); + + wifiConfigCommand = new WiFiConfigCommand( + handle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION); + + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret < 0) { + ALOGE("%s: failed to create NL msg. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + ret = wifiConfigCommand->set_iface_id(ifaceInfo->name); + if (ret < 0) { + ALOGE("%s: failed to set iface id. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY, 1)) { + ALOGE("%s: failed to put vendor data. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != 0) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return (wifi_error)ret; +} + +/** + * Set STA + STA use case + */ +wifi_error wifi_multi_sta_set_use_case(wifi_handle handle, + wifi_multi_sta_use_case case_info) +{ + int requestId, ret = 0; + u8 use_case; + WiFiConfigCommand *wifiConfigCommand; + if (!handle) { + ALOGE("%s: Error wifi_handle NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + struct nlattr *nlData; + hal_info *info = getHalInfo(handle); + if (!info || info->num_interfaces < 1) { + ALOGE("%s: Error wifi_handle NULL or base wlan interface not present", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ALOGD("%s: %d", __FUNCTION__, case_info); + + switch (case_info) { + case WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY: + use_case = QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY; + break; + case WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED: + use_case = QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED; + break; + default: + ALOGE("%s: Unknown use case %d", __FUNCTION__, case_info); + ret = WIFI_ERROR_UNKNOWN; + goto cleanup;; + } + + requestId = get_requestid(); + + wifiConfigCommand = new WiFiConfigCommand( + handle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY); + + if (wifiConfigCommand == NULL) { + ALOGE("%s: Error wifiConfigCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiConfigCommand->create(); + if (ret < 0) { + ALOGE("%s: failed to create NL msg. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + /* Set the interface Id of the message. */ + if (wifiConfigCommand->put_u32(NL80211_ATTR_IFINDEX, + info->interfaces[0]->id)) { + ALOGE("%s: Failed to put iface id", __FUNCTION__); + goto cleanup; + } + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiConfigCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) { + ALOGE("%s: failed attr_start for VENDOR_DATA. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + + if (wifiConfigCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG, use_case)) { + ALOGE("%s: failed to put use_case. Error:%d", + __FUNCTION__, ret); + goto cleanup; + } + wifiConfigCommand->attr_end(nlData); + + /* Send the NL msg. */ + wifiConfigCommand->waitForRsp(false); + ret = wifiConfigCommand->requestEvent(); + if (ret != 0) { + ALOGE("%s: requestEvent Error:%d", __FUNCTION__, ret); + goto cleanup; + } + +cleanup: + delete wifiConfigCommand; + return (wifi_error)ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h b/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h new file mode 100644 index 0000000..cc0f9e0 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wificonfigcommand.h @@ -0,0 +1,111 @@ +/* Copyright (c) 2014, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#ifndef __WIFI_HAL_WIFI_CONFIG_COMMAND_H__ +#define __WIFI_HAL_WIFI_CONFIG_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif +#include "wifi_config.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +int check_feature(enum qca_wlan_vendor_features feature, features_info *info); + +class WiFiConfigCommand: public WifiVendorCommand +{ +private: + int mRequestId; + bool mWaitforRsp; + +public: + WiFiConfigCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + virtual ~WiFiConfigCommand(); + + /* + * This function implements creation of WiFiConfigCommand specific Request + * based on the QCA vendor specific request type. + */ + virtual wifi_error create(); + /* + * This function implements creation of WiFiConfigCommand specific Request + * based on the generic NL request type. + */ + virtual wifi_error create_generic(u8 cmdId); + virtual void waitForRsp(bool wait); + virtual wifi_error requestEvent(); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/wifihal_internal.h b/wcn6740/qcwcn/wifi_hal/wifihal_internal.h new file mode 100644 index 0000000..5cc78c3 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifihal_internal.h @@ -0,0 +1,186 @@ +/* Copyright (c) 2014, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_LOWI_INTERNAL_H__ +#define __WIFI_HAL_LOWI_INTERNAL_H__ + +/* + * The file defines the interface by which wifihal can call LOWI for the + * purposes of initialization, rtt and gscan. + */ + +#include "wifi_hal.h" +#include "list.h" +#include "sys/un.h" + +#define WIFIHAL_LOWI_MAJOR_VERSION 2 +#define WIFIHAL_LOWI_MINOR_VERSION 1 +#define WIFIHAL_LOWI_MICRO_VERSION 1 + +/* LOWI supported capabilities bit masks */ +#define ONE_SIDED_RANGING_SUPPORTED 0x00000001 +#define DUAL_SIDED_RANGING_SUPPORED 0x00000002 +#define GSCAN_SUPPORTED 0x00000004 + +typedef struct wifihal_mon_sock_s { + + struct list_head list; + //! Family name + uint32_t family_name; + //! command ID + uint32_t cmd_id; + //! monitor sock len + uint32_t monsock_len; + //! monitor sock + struct sockaddr_un monsock; + //! match buff length + uint32_t match_len; + //! reserved byte + uint32_t reserved[4]; + //! match buff + char match[0]; +} wifihal_mon_sock_t; + +/* + * This structure is a table of function pointers to the functions + * used by the wifihal to interface with LOWI + */ +typedef struct +{ + /* lowi-client interface functions */ + int (*init)(); + int (*destroy)(); + /* rtt functions */ + int (*get_rtt_capabilities)(wifi_interface_handle iface, + wifi_rtt_capabilities *capabilities); + int (*rtt_range_request)(u32 request_id, + wifi_interface_handle iface, + u32 num_rtt_config, + wifi_rtt_config rtt_config[], + wifi_rtt_event_handler handler); + int (*rtt_range_cancel)(u32 request_id, + u32 num_devices, + mac_addr addr[]); + /* Additional lowi-client interface functions */ + int (*get_lowi_version) (u16* major_version, + u16* minor_version, + u16* micro_version); + int (*get_lowi_capabilities)(u32* capabilities); + /* gscan functions */ + wifi_error (*get_valid_channels)(wifi_interface_handle iface, + u32 band, + u32 max_channels, + wifi_channel *channels, + int *num_channels); + + wifi_error (*get_gscan_capabilities)(wifi_interface_handle handle, + wifi_gscan_capabilities *capabilities); + + wifi_error (*start_gscan)(wifi_request_id request_id, + wifi_interface_handle iface, + wifi_scan_cmd_params params, + wifi_scan_result_handler handler); + + wifi_error (*stop_gscan)(wifi_request_id request_id, + wifi_interface_handle iface); + + wifi_error (*get_cached_gscan_results)(wifi_interface_handle iface, + byte flush, + u32 max, + wifi_cached_scan_results *results, + int *num); + + wifi_error (*set_bssid_hotlist)(wifi_request_id request_id, + wifi_interface_handle iface, + wifi_bssid_hotlist_params params, + wifi_hotlist_ap_found_handler handler); + + wifi_error (*reset_bssid_hotlist)(wifi_request_id request_id, + wifi_interface_handle iface); + + wifi_error (*set_significant_change_handler)(wifi_request_id id, + wifi_interface_handle iface, + wifi_significant_change_params params, + wifi_significant_change_handler handler); + + wifi_error (*reset_significant_change_handler)(wifi_request_id id, + wifi_interface_handle iface); + + wifi_error (*set_ssid_hotlist)(wifi_request_id id, + wifi_interface_handle iface, + wifi_ssid_hotlist_params params, + wifi_hotlist_ssid_handler handler); + + wifi_error (*reset_ssid_hotlist)(wifi_request_id id, + wifi_interface_handle iface); + + // API to configure the LCI. Used in RTT Responder mode only + wifi_error (*rtt_set_lci)(wifi_request_id id, + wifi_interface_handle iface, + wifi_lci_information *lci); + + // API to configure the LCR. Used in RTT Responder mode only. + wifi_error (*rtt_set_lcr)(wifi_request_id id, + wifi_interface_handle iface, + wifi_lcr_information *lcr); + + /** + * Get RTT responder information e.g. WiFi channel to enable responder on. + */ + wifi_error (*rtt_get_responder_info)(wifi_interface_handle iface, + wifi_rtt_responder *responder_info); + + /** + * Enable RTT responder mode. + * channel_hint - hint of the channel information where RTT responder should + * be enabled on. + * max_duration_seconds - timeout of responder mode. + * responder_info - responder information e.g. channel used for RTT responder, + * NULL if responder is not enabled. + */ + wifi_error (*enable_responder)(wifi_request_id id, + wifi_interface_handle iface, + wifi_channel_info channel_hint, + unsigned max_duration_seconds, + wifi_rtt_responder *responder_info); + + /** + * Disable RTT responder mode. + */ + wifi_error (*disable_responder)(wifi_request_id id, + wifi_interface_handle iface); + +} lowi_cb_table_t; + +/* + * This is a function pointer to a function that gets the table + * of callback functions populated by LOWI and to be used by wifihal + */ +typedef lowi_cb_table_t* (getCbTable_t)(); + +#endif diff --git a/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp b/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp new file mode 100644 index 0000000..e94506f --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2017-2018, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#include "sync.h" + +#define LOG_TAG "WifiHAL" + +#include <utils/Log.h> + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include "wifihal_vendorcommand.h" + +#define MAX_INFO 1 +//Singleton Static Instance +NUDStatsCommand* NUDStatsCommand::mNUDStatsCommandInstance = NULL; + +// This function implements creation of Vendor command +// For NUDStats just call base Vendor command create +wifi_error NUDStatsCommand::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) { + return ret; + } + // insert the oui in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + goto out; + + // insert the subcmd in the msg + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + if (ret != WIFI_SUCCESS) + goto out; + +out: + return ret; +} + +NUDStatsCommand::NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + memset(&mStats, 0,sizeof(nud_stats)); + mpktInfo = NULL; + mnumStats = 0; +} + +NUDStatsCommand::~NUDStatsCommand() +{ + mNUDStatsCommandInstance = NULL; +} + +NUDStatsCommand* NUDStatsCommand::instance(wifi_handle handle) +{ + if (handle == NULL) { + ALOGE("Interface Handle is invalid"); + return NULL; + } + if (mNUDStatsCommandInstance == NULL) { + mNUDStatsCommandInstance = new NUDStatsCommand(handle, 0, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET); + return mNUDStatsCommandInstance; + } + else + { + if (handle != getWifiHandle(mNUDStatsCommandInstance->mInfo)) + { + /* upper layer must have cleaned up the handle and reinitialized, + so we need to update the same */ + ALOGE("Handle different, update the handle"); + mNUDStatsCommandInstance->mInfo = (hal_info *)handle; + } + } + return mNUDStatsCommandInstance; +} + +void NUDStatsCommand::setSubCmd(u32 subcmd) +{ + mSubcmd = subcmd; +} + +void NUDStatsCommand::setHandler(pkt_stats_result_handler handler) +{ + mHandler = handler; +} + +wifi_error NUDStatsCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +wifi_error NUDStatsCommand::notifyResponse() +{ + wifi_error ret = WIFI_SUCCESS; + + if (mHandler.on_pkt_stats_results) { + mHandler.on_pkt_stats_results(&mStats, mnumStats, + mpktInfo); + } else { + ret = WIFI_ERROR_INVALID_ARGS; + } + return ret; +} + +int NUDStatsCommand::handleResponse(WifiEvent &reply) +{ + wifi_error status = WIFI_ERROR_NONE; + WifiVendorCommand::handleResponse(reply); + + // Parse the vendordata and get the attribute + + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET: + { + struct nlattr *tb_vendor[QCA_ATTR_NUD_STATS_GET_MAX + 1]; + nud_stats *stats = &mStats; + + memset(stats, 0, sizeof(nud_stats)); + nla_parse(tb_vendor, QCA_ATTR_NUD_STATS_GET_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_req_count_from_netdev = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_req_count_to_lower_mac = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_req_rx_count_by_lower_mac = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_req_count_tx_success = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_rsp_rx_count_by_lower_mac = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_rsp_rx_count_by_upper_mac = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_rsp_count_to_netdev = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV]); + + if (!tb_vendor[QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP]) + { + ALOGE("%s: QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP" + " not found", __FUNCTION__); + status = WIFI_ERROR_INVALID_ARGS; + goto cleanup; + } + stats->arp_rsp_count_out_of_order_drop = nla_get_u16(tb_vendor[ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP]); + + if (tb_vendor[QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE]) + stats->ap_link_active = 1; + + if (tb_vendor[QCA_ATTR_NUD_STATS_IS_DAD]) + stats->is_duplicate_addr_detection = 1; + + ALOGV(" req_from_netdev %d count_to_lower :%d" + " count_by_lower :%d" + " count_tx_succ :%d rsp_count_lower :%d" + " rsp_count_upper :%d rsp_count_netdev :%d" + " out_of_order_drop :%d active_aplink %d" + " DAD %d ", + stats->arp_req_count_from_netdev, + stats->arp_req_count_to_lower_mac, + stats->arp_req_rx_count_by_lower_mac, + stats->arp_req_count_tx_success, + stats->arp_rsp_rx_count_by_lower_mac, + stats->arp_rsp_rx_count_by_upper_mac, + stats->arp_rsp_count_to_netdev, + stats->arp_rsp_count_out_of_order_drop, + stats->ap_link_active, + stats->is_duplicate_addr_detection); + + if (tb_vendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]) { + mNUDStatsCommandInstance->GetPktInfo(tb_vendor); + } + } + } +cleanup: + if (status == WIFI_ERROR_INVALID_ARGS) + memset(&mStats,0,sizeof(nud_stats)); + if(mpktInfo != NULL) + free(mpktInfo); + + return status; +} + +void NUDStatsCommand::GetPktInfo(struct nlattr **tbvendor) +{ + struct nlattr *tb; + int rem; + cmdData *pkt_stats; + char ipv6_address[INET6_ADDRSTRLEN]; + cmdData pktstats; + int nbuff = 0; + + for (tb = (struct nlattr *) nla_data(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]), + rem = nla_len(tbvendor[QCA_ATTR_NUD_STATS_DATA_PKT_STATS]); + nla_ok(tb, rem); tb = nla_next(tb, &(rem))) + { + struct nlattr *tb2[QCA_ATTR_NUD_DATA_STATS_MAX + 1]; + nla_parse(tb2, QCA_ATTR_NUD_DATA_STATS_MAX, + (struct nlattr *) nla_data(tb), nla_len(tb), NULL); + + memset(&pktstats, 0, sizeof(cmdData)); + + if (tb2[QCA_ATTR_NUD_STATS_PKT_TYPE]) + { + pktstats.pkt_Type = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_TYPE]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME]) + { + pktstats.domain_name = nla_get_string(tb2[QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT]) + { + pktstats.src_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_SRC_PORT]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT]) + { + pktstats.dst_port = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_PORT]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4]) + { + pktstats.ipv4_addr.s_addr = nla_get_u32(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV4]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6]) + { + memcpy(pktstats.ipv6_addr, nla_data(tb2[QCA_ATTR_NUD_STATS_PKT_DEST_IPV6]), + sizeof(pktstats.ipv6_addr)); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV]) + { + pktstats.stats.pkt_req_count_from_netdev = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC]) + { + pktstats.stats.pkt_req_count_to_lower_mac = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC]) + { + pktstats.stats.pkt_req_rx_count_by_lower_mac = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS]) + { + pktstats.stats.pkt_req_count_tx_success = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC]) + { + pktstats.stats.pkt_rsp_rx_count_by_lower_mac = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC]) + { + pktstats.stats.pkt_rsp_rx_count_by_upper_mac = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV]) + { + pktstats.stats.pkt_rsp_count_to_netdev = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV]); + } + + if (tb2[QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP]) + { + pktstats.stats.pkt_rsp_count_out_of_order_drop = nla_get_u16(tb2[ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP]); + } + + if (inet_ntop(AF_INET6, pktstats.ipv6_addr, ipv6_address, + INET6_ADDRSTRLEN) == NULL) { + ALOGE("%s: failed to convert ipv6 address format", __FUNCTION__); + } + + ALOGV(" pkt_type %d domain_name :%s" + " src_port %d dst_port :%d" + " ipv4_address :%x ipv6_address %s" + " req_from_netdev %d count_to_lower :%d" + " count_by_lower :%d" + " count_tx_succ :%d rsp_count_lower :%d" + " rsp_count_upper :%d rsp_count_netdev :%d" + " out_of_order_drop :%d ", + pktstats.pkt_Type, pktstats.domain_name, + pktstats.src_port, pktstats.dst_port, + pktstats.ipv4_addr.s_addr, ipv6_address, + pktstats.stats.pkt_req_count_from_netdev, + pktstats.stats.pkt_req_count_to_lower_mac, + pktstats.stats.pkt_req_rx_count_by_lower_mac, + pktstats.stats.pkt_req_count_tx_success, + pktstats.stats.pkt_rsp_rx_count_by_lower_mac, + pktstats.stats.pkt_rsp_rx_count_by_upper_mac, + pktstats.stats.pkt_rsp_count_to_netdev, + pktstats.stats.pkt_rsp_count_out_of_order_drop); + + if (nbuff == 0) + pkt_stats = (cmdData *)malloc(sizeof(cmdData)); + else + pkt_stats = (cmdData *)realloc(pkt_stats,sizeof(cmdData) * (nbuff + 1)); + + mpktInfo = pkt_stats; + if (pkt_stats != NULL) { + memcpy(&pkt_stats[nbuff], &pktstats,sizeof(cmdData)); + nbuff++; + mnumStats = nbuff; + } + } +} + +void NUDStatsCommand::copyStats(nud_stats *stats, cmdData *pktstats) +{ + memcpy(stats, &mStats, sizeof(nud_stats)); + pktstats = mpktInfo; +} + +wifi_error wifi_set_nud_stats(wifi_interface_handle iface, + u32 gw_addr, cmdData Data) +{ + wifi_error ret; + NUDStatsCommand *NUDCommand; + struct nlattr *nl_data,*nl_pktInfo; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + cmdData mData = Data; + cmdData pktstats = Data; + + ALOGV("gw_addr : %x", gw_addr); + NUDCommand = NUDStatsCommand::instance(handle); + if (NUDCommand == NULL) { + ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET); + + /* create the message */ + ret = NUDCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = NUDCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the attributes*/ + nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + /**/ + ret = NUDCommand->put_flag(QCA_ATTR_NUD_STATS_SET_START); + + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_GW_IPV4, gw_addr); + if (ret != WIFI_SUCCESS) + goto cleanup; + + if (mData.pkt_Type) { + /*start the packet info attributes in nested*/ + nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO); + if (!nl_pktInfo) + goto cleanup; + else { + ALOGV(" pkt_type %d domain_name :%s" + " src_port %d dst_port :%d" + " ipv4_address :%x ipv6_address %s", + pktstats.pkt_Type, pktstats.domain_name, + pktstats.src_port, pktstats.dst_port, + pktstats.ipv4_addr.s_addr,pktstats.ipv6_addr); + + for (int i=0; i < MAX_INFO ; i++) { + /*add the packet type attributes*/ + struct nlattr *tb_tmp; + tb_tmp = NUDCommand->attr_start(i); + + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type); + if (ret != WIFI_SUCCESS) + goto cleanup; + + if (mData.domain_name) { + /*add the domain name attributes*/ + ret = NUDCommand->put_string(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME, + mData.domain_name); + if (ret != WIFI_SUCCESS) + goto cleanup; + } + /*add the source port attributes*/ + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT, + mData.src_port); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the dest port attributes*/ + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT, + mData.dst_port); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the ipv4 address attributes*/ + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4, + mData.ipv4_addr.s_addr); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the ipv6 address attributes*/ + ret = NUDCommand->put_ipv6_addr(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6, + mData.ipv6_addr); + if (ret != WIFI_SUCCESS) + goto cleanup; + NUDCommand->attr_end(tb_tmp); + } + } + NUDCommand->attr_end(nl_pktInfo); + } + NUDCommand->attr_end(nl_data); + + ret = NUDCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + } + +cleanup: + return ret; +} + + +wifi_error wifi_get_nud_stats(wifi_interface_handle iface, + pkt_stats_result_handler handler) +{ + wifi_error ret; + NUDStatsCommand *NUDCommand; + struct nlattr *nl_data; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + + NUDCommand = NUDStatsCommand::instance(handle); + if (NUDCommand == NULL) { + ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET); + + NUDCommand->setHandler(handler); + + /* create the message */ + ret = NUDCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = NUDCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + /*add the attributes*/ + nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + /**/ + NUDCommand->attr_end(nl_data); + + ret = NUDCommand->requestResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + + ret = NUDCommand->notifyResponse(); + if (ret != WIFI_SUCCESS) { + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + goto cleanup; + } + +cleanup: + return ret; +} + + +wifi_error wifi_clear_nud_stats(wifi_interface_handle iface, + cmdData Data) +{ + wifi_error ret; + NUDStatsCommand *NUDCommand; + struct nlattr *nl_data,*nl_pktInfo; + interface_info *iinfo = getIfaceInfo(iface); + wifi_handle handle = getWifiHandle(iface); + cmdData mData = Data; + + NUDCommand = NUDStatsCommand::instance(handle); + if (NUDCommand == NULL) { + ALOGE("%s: Error NUDStatsCommand NULL", __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + NUDCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET); + + /* create the message */ + ret = NUDCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = NUDCommand->set_iface_id(iinfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /*add the attributes*/ + nl_data = NUDCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nl_data) + goto cleanup; + if (mData.pkt_Type) { + /*set the packet info attributes in nested*/ + nl_pktInfo = NUDCommand->attr_start(QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO); + if (!nl_pktInfo) + goto cleanup; + else { + ALOGV(" %s: pkt_type %d domain_name :%s" + " src_port %d dst_port :%d" + " ipv4_address :%x ipv6_address %s", + __FUNCTION__,mData.pkt_Type, mData.domain_name, + mData.src_port, mData.dst_port, + mData.ipv4_addr.s_addr,mData.ipv6_addr); + + for (int i=0; i < MAX_INFO ; i++) { + /*add the packet type attributes*/ + struct nlattr *tb_tmp; + tb_tmp = NUDCommand->attr_start(i); + + ret = NUDCommand->put_u32(QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE,mData.pkt_Type); + if (ret != WIFI_SUCCESS) + goto cleanup; + + NUDCommand->attr_end(tb_tmp); + } + } + NUDCommand->attr_end(nl_pktInfo); + } + NUDCommand->attr_end(nl_data); + + ret = NUDCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: requestResponse Error:%d",__FUNCTION__, ret); + +cleanup: + return ret; +} diff --git a/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h b/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h new file mode 100644 index 0000000..123fe1e --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017-2018, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_NUDSTATSCOMMAND_H__ +#define __WIFI_HAL_NUDSTATSCOMMAND_H__ + +#include "nud_stats.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +class NUDStatsCommand: public WifiVendorCommand +{ +private: + static NUDStatsCommand *mNUDStatsCommandInstance; + + pkt_stats_result_handler mHandler; + nud_stats mStats; + cmdData *mpktInfo; + int mnumStats; + NUDStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + +public: + static NUDStatsCommand* instance(wifi_handle handle); + + virtual ~NUDStatsCommand(); + + // This function implements creation of NUDStats specific Request + // based on the request type + virtual wifi_error create(); + + virtual void setSubCmd(u32 subcmd); + + virtual wifi_error requestResponse(); + + virtual wifi_error notifyResponse(); + + virtual int handleResponse(WifiEvent &reply); + + virtual void setHandler(pkt_stats_result_handler handler); + + void copyStats(nud_stats *stats, cmdData *pktdstats); + + void GetPktInfo(struct nlattr **tbvendor); +}; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger.cpp b/wcn6740/qcwcn/wifi_hal/wifilogger.cpp new file mode 100644 index 0000000..96e9911 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifilogger.cpp @@ -0,0 +1,1518 @@ +/* Copyright (c) 2015, 2018 The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "sync.h" + +#include "wifi_hal.h" +#include "common.h" +#include "cpp_bindings.h" +#include <errno.h> +#include <utils/Log.h> +#include "wifiloggercmd.h" +#include "rb_wrapper.h" +#include <stdlib.h> + +#define LOGGER_MEMDUMP_FILENAME "/proc/debug/fwdump" +#define DRIVER_MEMDUMP_FILENAME "/proc/debugdriver/driverdump" +#define LOGGER_MEMDUMP_CHUNKSIZE (4 * 1024) +#define DRIVER_MEMDUMP_MAX_FILESIZE (16 * 1024) + +char power_events_ring_name[] = "power_events_rb"; +char connectivity_events_ring_name[] = "connectivity_events_rb"; +char pkt_stats_ring_name[] = "pkt_stats_rb"; +char driver_prints_ring_name[] = "driver_prints_rb"; +char firmware_prints_ring_name[] = "firmware_prints_rb"; + +static int get_ring_id(hal_info *info, char *ring_name) +{ + int rb_id; + + for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) { + if (is_rb_name_match(&info->rb_infos[rb_id], ring_name)) { + return rb_id; + } + } + return -1; +} + +//Implementation of the functions exposed in wifi_logger.h + +/* Function to intiate logging */ +wifi_error wifi_start_logging(wifi_interface_handle iface, + u32 verbose_level, u32 flags, + u32 max_interval_sec, u32 min_data_size, + char *buffer_name) +{ + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand = NULL; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + int ring_id = 0; + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) { + ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__, + info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + /* + * No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid(); + + if (buffer_name == NULL) { + ALOGE("%s: Invalid Ring Name. \n", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + ring_id = get_ring_id(info, buffer_name); + if (ring_id < 0) { + ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START); + + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, + ring_id); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = wifiLoggerCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL, + verbose_level); + if (ret != WIFI_SUCCESS) + goto cleanup; + + ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS, + flags); + if (ret != WIFI_SUCCESS) + goto cleanup; + + wifiLoggerCommand->attr_end(nlData); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + + ALOGV("%s: Logging Started for %s. with verboselevel %d", + __FUNCTION__, buffer_name,verbose_level); + rb_start_logging(&info->rb_infos[ring_id], verbose_level, + flags, max_interval_sec, min_data_size); +cleanup: + delete wifiLoggerCommand; + return ret; +} + +/* Function to get each ring related info */ +wifi_error wifi_get_ring_buffers_status(wifi_interface_handle iface, + u32 *num_buffers, + wifi_ring_buffer_status *status) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + wifi_ring_buffer_status *rbs; + struct rb_info *rb_info; + int rb_id; + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) { + ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__, + info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if ((*num_buffers) < NUM_RING_BUFS) { + ALOGE("%s: Input num_buffers:%u cannot be accommodated, " + "Total ring buffer num:%d", __FUNCTION__, *num_buffers, + NUM_RING_BUFS); + *num_buffers = 0; + return WIFI_ERROR_OUT_OF_MEMORY; + } + for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) { + rb_info = &info->rb_infos[rb_id]; + rbs = status + rb_id; + + get_rb_status(rb_info, rbs); + } + *num_buffers = NUM_RING_BUFS; + return WIFI_SUCCESS; +} + +void push_out_all_ring_buffers(hal_info *info) +{ + int rb_id; + + for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) { + push_out_rb_data(&info->rb_infos[rb_id]); + } +} + +void send_alert(hal_info *info, int reason_code) +{ + wifi_alert_handler handler; + char alert_msg[20] = "Fatal Event"; + pthread_mutex_lock(&info->ah_lock); + handler.on_alert = info->on_alert; + pthread_mutex_unlock(&info->ah_lock); + + if (handler.on_alert) { + handler.on_alert(0, alert_msg, strlen(alert_msg), reason_code); + } +} + +void WifiLoggerCommand::setFeatureSet(u32 *support) { + mSupportedSet = support; +} + +/* Function to get the supported feature set for logging.*/ +wifi_error wifi_get_logger_supported_feature_set(wifi_interface_handle iface, + u32 *support) +{ + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid(); + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET); + + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = wifiLoggerCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED, + requestId); + if (ret != WIFI_SUCCESS) + goto cleanup; + + wifiLoggerCommand->attr_end(nlData); + + wifiLoggerCommand->setFeatureSet(support); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; +} + +/* Function to get the data in each ring for the given ring ID.*/ +wifi_error wifi_get_ring_data(wifi_interface_handle iface, + char *ring_name) +{ + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + int ring_id = 0; + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) { + ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__, + info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ring_id = get_ring_id(info, ring_name); + if (ring_id < 0) { + ALOGE("%s: Invalid Ring Buffer Name ", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + requestId = get_requestid(); + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA); + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + if (wifiLoggerCommand->put_u32( + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID, ring_id)) + { + goto cleanup; + } + wifiLoggerCommand->attr_end(nlData); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; +} + +void WifiLoggerCommand::setVersionInfo(char *buffer, int buffer_size) { + mVersion = buffer; + mVersionLen = buffer_size; +} + +/* Function to send enable request to the wifi driver.*/ +wifi_error wifi_get_firmware_version(wifi_interface_handle iface, + char *buffer, int buffer_size) +{ + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid_u8(); + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO); + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = wifiLoggerCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION, requestId); + if (ret != WIFI_SUCCESS) + goto cleanup; + + wifiLoggerCommand->attr_end(nlData); + + wifiLoggerCommand->setVersionInfo(buffer, buffer_size); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; + +} + +/* Function to get wlan driver version.*/ +wifi_error wifi_get_driver_version(wifi_interface_handle iface, + char *buffer, int buffer_size) +{ + + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid_u8(); + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO); + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + ret = wifiLoggerCommand->put_u8( + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION, requestId); + if (ret != WIFI_SUCCESS) + goto cleanup; + + wifiLoggerCommand->attr_end(nlData); + + wifiLoggerCommand->setVersionInfo(buffer, buffer_size); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; +} + + +/* Function to get the Firmware memory dump. */ +wifi_error wifi_get_firmware_memory_dump(wifi_interface_handle iface, + wifi_firmware_memory_dump_handler handler) +{ + wifi_error ret; + int requestId; + WifiLoggerCommand *wifiLoggerCommand; + struct nlattr *nlData; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & + WIFI_LOGGER_MEMORY_DUMP_SUPPORTED)) { + ALOGE("%s: Firmware memory dump logging feature not supported %x", + __FUNCTION__, info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate one randomly. + */ + requestId = get_requestid(); + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP); + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Add the vendor specific attributes for the NL command. */ + nlData = wifiLoggerCommand->attr_start(NL80211_ATTR_VENDOR_DATA); + if (!nlData) + goto cleanup; + + wifiLoggerCommand->attr_end(nlData); + + /* copy the callback into callback handler */ + WifiLoggerCallbackHandler callbackHandler; + memset(&callbackHandler, 0, sizeof(callbackHandler)); + callbackHandler.on_firmware_memory_dump = \ + handler.on_firmware_memory_dump; + + ret = wifiLoggerCommand->setCallbackHandler(callbackHandler); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Send the msg and wait for the memory dump response */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; +} + +wifi_error wifi_set_log_handler(wifi_request_id id, + wifi_interface_handle iface, + wifi_ring_buffer_data_handler handler) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + pthread_mutex_lock(&info->lh_lock); + info->on_ring_buffer_data = handler.on_ring_buffer_data; + pthread_mutex_unlock(&info->lh_lock); + if (handler.on_ring_buffer_data == NULL) { + ALOGE("Set log handler is NULL"); + return WIFI_ERROR_UNKNOWN; + } + return WIFI_SUCCESS; +} + +wifi_error wifi_reset_log_handler(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + pthread_mutex_lock(&info->lh_lock); + info->on_ring_buffer_data = NULL; + pthread_mutex_unlock(&info->lh_lock); + return WIFI_SUCCESS; +} + +wifi_error wifi_set_alert_handler(wifi_request_id id, + wifi_interface_handle iface, + wifi_alert_handler handler) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + if (handler.on_alert == NULL) { + ALOGE("Set alert handler is NULL"); + return WIFI_ERROR_UNKNOWN; + } + pthread_mutex_lock(&info->ah_lock); + info->on_alert = handler.on_alert; + pthread_mutex_unlock(&info->ah_lock); + return WIFI_SUCCESS; +} + +wifi_error wifi_reset_alert_handler(wifi_request_id id, + wifi_interface_handle iface) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + pthread_mutex_lock(&info->ah_lock); + info->on_alert = NULL; + pthread_mutex_unlock(&info->ah_lock); + return WIFI_SUCCESS; +} + + +/** + API to start packet fate monitoring. + - Once stared, monitoring should remain active until HAL is unloaded. + - When HAL is unloaded, all packet fate buffers should be cleared. +*/ +wifi_error wifi_start_pkt_fate_monitoring(wifi_interface_handle iface) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & + WIFI_LOGGER_PACKET_FATE_SUPPORTED)) { + ALOGE("%s: packet fate logging feature not supported %x", + __FUNCTION__, info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + if (info->fate_monitoring_enabled == true) { + ALOGV("Packet monitoring is already enabled"); + return WIFI_SUCCESS; + } + + info->pkt_fate_stats = (packet_fate_monitor_info *) malloc ( + sizeof(packet_fate_monitor_info)); + if (info->pkt_fate_stats == NULL) { + ALOGE("Failed to allocate memory for : %zu bytes", + sizeof(packet_fate_monitor_info)); + return WIFI_ERROR_OUT_OF_MEMORY; + } + memset(info->pkt_fate_stats, 0, sizeof(packet_fate_monitor_info)); + + pthread_mutex_lock(&info->pkt_fate_stats_lock); + info->fate_monitoring_enabled = true; + pthread_mutex_unlock(&info->pkt_fate_stats_lock); + + return WIFI_SUCCESS; +} + + +/** + API to retrieve fates of outbound packets. + - HAL implementation should fill |tx_report_bufs| with fates of + _first_ min(n_requested_fates, actual packets) frames + transmitted for the most recent association. The fate reports + should follow the same order as their respective packets. + - Packets reported by firmware, but not recognized by driver + should be included. However, the ordering of the corresponding + reports is at the discretion of HAL implementation. + - Framework may call this API multiple times for the same association. + - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|. + - Framework will allocate and free the referenced storage. +*/ +wifi_error wifi_get_tx_pkt_fates(wifi_interface_handle iface, + wifi_tx_report *tx_report_bufs, + size_t n_requested_fates, + size_t *n_provided_fates) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + wifi_tx_report_i *tx_fate_stats; + size_t i; + + if (info->fate_monitoring_enabled != true) { + ALOGE("Packet monitoring is not yet triggered"); + return WIFI_ERROR_UNINITIALIZED; + } + pthread_mutex_lock(&info->pkt_fate_stats_lock); + + tx_fate_stats = &info->pkt_fate_stats->tx_fate_stats[0]; + + *n_provided_fates = min(n_requested_fates, + info->pkt_fate_stats->n_tx_stats_collected); + + for (i=0; i < *n_provided_fates; i++) { + memcpy(tx_report_bufs[i].md5_prefix, + tx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN); + tx_report_bufs[i].fate = tx_fate_stats[i].fate; + tx_report_bufs[i].frame_inf.payload_type = + tx_fate_stats[i].frame_inf.payload_type; + tx_report_bufs[i].frame_inf.driver_timestamp_usec = + tx_fate_stats[i].frame_inf.driver_timestamp_usec; + tx_report_bufs[i].frame_inf.firmware_timestamp_usec = + tx_fate_stats[i].frame_inf.firmware_timestamp_usec; + tx_report_bufs[i].frame_inf.frame_len = + tx_fate_stats[i].frame_inf.frame_len; + + if (tx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II) + memcpy(tx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes, + tx_fate_stats[i].frame_inf.frame_content, + min(tx_fate_stats[i].frame_inf.frame_len, + MAX_FRAME_LEN_ETHERNET)); + else if (tx_report_bufs[i].frame_inf.payload_type == + FRAME_TYPE_80211_MGMT) + memcpy( + tx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes, + tx_fate_stats[i].frame_inf.frame_content, + min(tx_fate_stats[i].frame_inf.frame_len, + MAX_FRAME_LEN_80211_MGMT)); + else + /* Currently framework is interested only two types( + * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so + * ignore the all other types of packets received from driver */ + ALOGI("Unknown format packet"); + } + pthread_mutex_unlock(&info->pkt_fate_stats_lock); + + return WIFI_SUCCESS; +} + +/** + API to retrieve fates of inbound packets. + - HAL implementation should fill |rx_report_bufs| with fates of + _first_ min(n_requested_fates, actual packets) frames + received for the most recent association. The fate reports + should follow the same order as their respective packets. + - Packets reported by firmware, but not recognized by driver + should be included. However, the ordering of the corresponding + reports is at the discretion of HAL implementation. + - Framework may call this API multiple times for the same association. + - Framework will ensure |n_requested_fates <= MAX_FATE_LOG_LEN|. + - Framework will allocate and free the referenced storage. +*/ +wifi_error wifi_get_rx_pkt_fates(wifi_interface_handle iface, + wifi_rx_report *rx_report_bufs, + size_t n_requested_fates, + size_t *n_provided_fates) +{ + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + wifi_rx_report_i *rx_fate_stats; + size_t i; + + if (info->fate_monitoring_enabled != true) { + ALOGE("Packet monitoring is not yet triggered"); + return WIFI_ERROR_UNINITIALIZED; + } + pthread_mutex_lock(&info->pkt_fate_stats_lock); + + rx_fate_stats = &info->pkt_fate_stats->rx_fate_stats[0]; + + *n_provided_fates = min(n_requested_fates, + info->pkt_fate_stats->n_rx_stats_collected); + + for (i=0; i < *n_provided_fates; i++) { + memcpy(rx_report_bufs[i].md5_prefix, + rx_fate_stats[i].md5_prefix, MD5_PREFIX_LEN); + rx_report_bufs[i].fate = rx_fate_stats[i].fate; + rx_report_bufs[i].frame_inf.payload_type = + rx_fate_stats[i].frame_inf.payload_type; + rx_report_bufs[i].frame_inf.driver_timestamp_usec = + rx_fate_stats[i].frame_inf.driver_timestamp_usec; + rx_report_bufs[i].frame_inf.firmware_timestamp_usec = + rx_fate_stats[i].frame_inf.firmware_timestamp_usec; + rx_report_bufs[i].frame_inf.frame_len = + rx_fate_stats[i].frame_inf.frame_len; + + if (rx_report_bufs[i].frame_inf.payload_type == FRAME_TYPE_ETHERNET_II) + memcpy(rx_report_bufs[i].frame_inf.frame_content.ethernet_ii_bytes, + rx_fate_stats[i].frame_inf.frame_content, + min(rx_fate_stats[i].frame_inf.frame_len, + MAX_FRAME_LEN_ETHERNET)); + else if (rx_report_bufs[i].frame_inf.payload_type == + FRAME_TYPE_80211_MGMT) + memcpy( + rx_report_bufs[i].frame_inf.frame_content.ieee_80211_mgmt_bytes, + rx_fate_stats[i].frame_inf.frame_content, + min(rx_fate_stats[i].frame_inf.frame_len, + MAX_FRAME_LEN_80211_MGMT)); + else + /* Currently framework is interested only two types( + * FRAME_TYPE_ETHERNET_II and FRAME_TYPE_80211_MGMT) of packets, so + * ignore the all other types of packets received from driver */ + ALOGI("Unknown format packet"); + } + pthread_mutex_unlock(&info->pkt_fate_stats_lock); + + return WIFI_SUCCESS; +} + +WifiLoggerCommand::WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd) + : WifiVendorCommand(handle, id, vendor_id, subcmd) +{ + mVersion = NULL; + mVersionLen = 0; + mRequestId = id; + memset(&mHandler, 0,sizeof(mHandler)); + mWaitforRsp = false; + mMoreData = false; + mSupportedSet = NULL; +} + +WifiLoggerCommand::~WifiLoggerCommand() +{ + unregisterVendorHandler(mVendor_id, mSubcmd); +} + +/* This function implements creation of Vendor command */ +wifi_error WifiLoggerCommand::create() { + wifi_error ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0); + if (ret != WIFI_SUCCESS) + return ret; + + /* Insert the oui in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id); + if (ret != WIFI_SUCCESS) + goto out; + /* Insert the subcmd in the msg */ + ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd); + if (ret != WIFI_SUCCESS) + goto out; + + ALOGV("%s: mVendor_id = %d, Subcmd = %d.", + __FUNCTION__, mVendor_id, mSubcmd); + +out: + return ret; +} + +void rb_timerhandler(hal_info *info) +{ + struct timeval now; + int rb_id; + + gettimeofday(&now,NULL); + for (rb_id = 0; rb_id < NUM_RING_BUFS; rb_id++) { + rb_check_for_timeout(&info->rb_infos[rb_id], &now); + } +} + +wifi_error wifi_logger_ring_buffers_init(hal_info *info) +{ + wifi_error ret; + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) { + ALOGE("%s: Ring buffer logging feature not supported %x", __FUNCTION__, + info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + ret = rb_init(info, &info->rb_infos[POWER_EVENTS_RB_ID], + POWER_EVENTS_RB_ID, + POWER_EVENTS_RB_BUF_SIZE, + POWER_EVENTS_NUM_BUFS, + power_events_ring_name); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to initialize power events ring buffer"); + goto cleanup; + } + + ret = rb_init(info, &info->rb_infos[CONNECTIVITY_EVENTS_RB_ID], + CONNECTIVITY_EVENTS_RB_ID, + CONNECTIVITY_EVENTS_RB_BUF_SIZE, + CONNECTIVITY_EVENTS_NUM_BUFS, + connectivity_events_ring_name); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to initialize connectivity events ring buffer"); + goto cleanup; + } + + ret = rb_init(info, &info->rb_infos[PKT_STATS_RB_ID], + PKT_STATS_RB_ID, + PKT_STATS_RB_BUF_SIZE, + PKT_STATS_NUM_BUFS, + pkt_stats_ring_name); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to initialize per packet stats ring buffer"); + goto cleanup; + } + + ret = rb_init(info, &info->rb_infos[DRIVER_PRINTS_RB_ID], + DRIVER_PRINTS_RB_ID, + DRIVER_PRINTS_RB_BUF_SIZE, + DRIVER_PRINTS_NUM_BUFS, + driver_prints_ring_name); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to initialize driver prints ring buffer"); + goto cleanup; + } + + ret = rb_init(info, &info->rb_infos[FIRMWARE_PRINTS_RB_ID], + FIRMWARE_PRINTS_RB_ID, + FIRMWARE_PRINTS_RB_BUF_SIZE, + FIRMWARE_PRINTS_NUM_BUFS, + firmware_prints_ring_name); + if (ret != WIFI_SUCCESS) { + ALOGE("Failed to initialize firmware prints ring buffer"); + goto cleanup; + } + + pthread_mutex_init(&info->lh_lock, NULL); + pthread_mutex_init(&info->ah_lock, NULL); + + return ret; + +cleanup: + wifi_logger_ring_buffers_deinit(info); + return ret; +} + +void wifi_logger_ring_buffers_deinit(hal_info *info) +{ + int i; + + if (!(info->supported_logger_feature_set & LOGGER_RING_BUFFER)) + return; + + for (i = 0; i < NUM_RING_BUFS; i++) { + rb_deinit(&info->rb_infos[i]); + } + pthread_mutex_destroy(&info->lh_lock); + pthread_mutex_destroy(&info->ah_lock); +} + + +/* Callback handlers registered for nl message send */ +static int error_handler_wifi_logger(struct sockaddr_nl *nla, + struct nlmsgerr *err, + void *arg) +{ + struct sockaddr_nl *tmp; + int *ret = (int *)arg; + tmp = nla; + *ret = err->error; + ALOGE("%s: Error code:%d (%s)", __FUNCTION__, *ret, strerror(-(*ret))); + return NL_STOP; +} + +/* Callback handlers registered for nl message send */ +static int ack_handler_wifi_logger(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + a = msg; + *ret = 0; + return NL_STOP; +} + +/* Callback handlers registered for nl message send */ +static int finish_handler_wifi_logger(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + struct nl_msg * a; + + a = msg; + *ret = 0; + return NL_SKIP; +} + +wifi_error WifiLoggerCommand::requestEvent() +{ + int status; + wifi_error res = WIFI_SUCCESS; + struct nl_cb *cb = NULL; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + ALOGE("%s: Callback allocation failed",__FUNCTION__); + res = WIFI_ERROR_OUT_OF_MEMORY; + goto out; + } + + /* Send message */ + status = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); + if (status < 0) { + res = mapKernelErrortoWifiHalError(status); + goto out; + } + + status = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler_wifi_logger, &status); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler_wifi_logger, &status); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler_wifi_logger, &status); + + /* Err is populated as part of finish_handler. */ + while (status > 0){ + nl_recvmsgs(mInfo->cmd_sock, cb); + } + + ALOGV("%s: Msg sent, status=%d, mWaitForRsp=%d", __FUNCTION__, status, mWaitforRsp); + /* Only wait for the asynchronous event if HDD returns success, res=0 */ + if (!status && (mWaitforRsp == true)) { + struct timespec abstime; + abstime.tv_sec = 4; + abstime.tv_nsec = 0; + res = mCondition.wait(abstime); + if (res == WIFI_ERROR_TIMED_OUT) + ALOGE("%s: Time out happened.", __FUNCTION__); + + ALOGV("%s: Command invoked return value:%d, mWaitForRsp=%d", + __FUNCTION__, res, mWaitforRsp); + } +out: + nl_cb_put(cb); + /* Cleanup the mMsg */ + mMsg.destroy(); + return res; +} + +wifi_error WifiLoggerCommand::requestResponse() +{ + return WifiCommand::requestResponse(mMsg); +} + +int WifiLoggerCommand::handleResponse(WifiEvent &reply) { + int len = 0, version; + char version_type[20]; + char* memBuffer = NULL; + FILE* memDumpFilePtr = NULL; + WifiVendorCommand::handleResponse(reply); + + memset(version_type, 0, 20); + switch(mSubcmd) + { + case QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO: + { + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1]; + + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) { + len = nla_len(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]); + memcpy(version_type, "Driver", strlen("Driver")); + version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION; + } else if ( + tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) { + len = nla_len( + tb_vendor[ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]); + memcpy(version_type, "Firmware", strlen("Firmware")); + version = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION; + } + if (len && mVersion && mVersionLen) { + memset(mVersion, 0, mVersionLen); + /* if len is greater than the incoming length then + accommodate 1 lesser than mVersionLen to have the + string terminated with '\0' */ + len = (len > mVersionLen)? (mVersionLen - 1) : len; + memcpy(mVersion, nla_data(tb_vendor[version]), len); + ALOGV("%s: WLAN %s version : %s ", __FUNCTION__, + version_type, mVersion); + } + } + break; + case QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET: + { + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_MAX + 1]; + + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LOGGER_MAX, + (struct nlattr *)mVendorData, mDataLen, NULL); + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]) { + *mSupportedSet = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED]); +#ifdef QC_HAL_DEBUG + ALOGV("%s: Supported Feature Set : val 0x%x", + __FUNCTION__, *mSupportedSet); +#endif + } + } + break; + + case QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP: + { + u32 memDumpSize = 0; + int numRecordsRead = 0; + u32 remaining = 0; + char* buffer = NULL; + struct nlattr *tbVendor[ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX + 1]; + + nla_parse(tbVendor, QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE]) { + ALOGE("%s: LOGGER_RESULTS_MEMDUMP_SIZE not" + "found", __FUNCTION__); + break; + } + + memDumpSize = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE] + ); + + /* Allocate the memory indicated in memDumpSize */ + memBuffer = (char*) malloc(sizeof(char) * memDumpSize); + if (memBuffer == NULL) { + ALOGE("%s: No Memory for allocating Buffer size of %d", + __func__, memDumpSize); + break; + } + memset(memBuffer, 0, sizeof(char) * memDumpSize); + + ALOGI("%s: Memory Dump size: %u", __func__, + memDumpSize); + + /* Open the proc or debugfs filesystem */ + memDumpFilePtr = fopen(LOGGER_MEMDUMP_FILENAME, "r"); + if (memDumpFilePtr == NULL) { + ALOGE("Failed to open %s file", LOGGER_MEMDUMP_FILENAME); + break; + } + + /* Read the memDumpSize value at once */ + numRecordsRead = fread(memBuffer, 1, memDumpSize, + memDumpFilePtr); + if (numRecordsRead <= 0 || + numRecordsRead != (int) memDumpSize) { + ALOGE("%s: Read %d failed for reading at once.", + __func__, numRecordsRead); + /* Lets try to read in chunks */ + rewind(memDumpFilePtr); + remaining = memDumpSize; + buffer = memBuffer; + while (remaining) { + u32 readSize = 0; + if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE) { + readSize = LOGGER_MEMDUMP_CHUNKSIZE; + } + else { + readSize = remaining; + } + numRecordsRead = fread(buffer, 1, + readSize, memDumpFilePtr); + if (numRecordsRead) { + remaining -= readSize; + buffer += readSize; + ALOGV("%s: Read successful for size:%u " + "remaining:%u", __func__, readSize, + remaining); + } + else { + ALOGE("%s: Chunk read failed for size:%u", + __func__, readSize); + break; + } + } + } + + /* After successful read, call the callback handler*/ + if (mHandler.on_firmware_memory_dump) { + mHandler.on_firmware_memory_dump(memBuffer, + memDumpSize); + + } + } + break; + case QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS: + { + struct nlattr *tbVendor[QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX+1]; + + /* parse and extract wake reason stats */ + nla_parse(tbVendor, QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX, + (struct nlattr *)mVendorData, + mDataLen, NULL); + + mGetWakeStats->cmd_event_wake_cnt_used = 0; + + mGetWakeStats->driver_fw_local_wake_cnt_used = 0; + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]) { + ALOGE("%s: TOTAL_RX_DATA_WAKE not found", __FUNCTION__); + break; + } + mGetWakeStats->total_rx_data_wake = nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]) { + ALOGE("%s: RX_UNICAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_details.rx_unicast_cnt = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]) { + ALOGE("%s: RX_MULTICAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_details.rx_multicast_cnt = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]) { + ALOGE("%s: RX_BROADCAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_details.rx_broadcast_cnt = nla_get_u32( + tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]) { + ALOGE("%s: ICMP_PKT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_pkt_classification_info.icmp_pkt = + nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]) { + ALOGE("%s: ICMP6_PKT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_pkt_classification_info.icmp6_pkt = + nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]) { + ALOGE("%s: ICMP6_RA not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ra = + nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]) { + ALOGE("%s: ICMP6_NA not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_pkt_classification_info.icmp6_na = + nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA]); + + if (!tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]) { + ALOGE("%s: ICMP6_NS not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_wake_pkt_classification_info.icmp6_ns = + nla_get_u32(tbVendor[QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS]); + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]) { + ALOGE("%s: ICMP4_RX_MULTICAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt = + nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT]); + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]) { + ALOGE("%s: ICMP6_RX_MULTICAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt = + nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT]); + + if (!tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]) { + ALOGE("%s: OTHER_RX_MULTICAST_CNT not found", __FUNCTION__); + break; + } + mGetWakeStats->rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt = + nla_get_u32(tbVendor[ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT]); + + } + break; + + default : + ALOGE("%s: Wrong Wifi Logger subcmd response received %d", + __FUNCTION__, mSubcmd); + } + + /* free the allocated memory */ + if (memBuffer) { + free(memBuffer); + } + if (memDumpFilePtr) { + fclose(memDumpFilePtr); + } + return NL_SKIP; +} + +/* This function will be the main handler for incoming (from driver) + * WIFI_LOGGER_SUBCMD. + * Calls the appropriate callback handler after parsing the vendor data. + */ +int WifiLoggerCommand::handleEvent(WifiEvent &event) +{ + WifiVendorCommand::handleEvent(event); + + switch(mSubcmd) + { + default: + /* Error case should not happen print log */ + ALOGE("%s: Wrong subcmd received %d", __func__, mSubcmd); + break; + } + + return NL_SKIP; +} + +wifi_error WifiLoggerCommand::setCallbackHandler(WifiLoggerCallbackHandler nHandler) +{ + wifi_error res; + mHandler = nHandler; + res = registerVendorHandler(mVendor_id, mSubcmd); + if (res != WIFI_SUCCESS) { + ALOGE("%s: Unable to register Vendor Handler Vendor Id=0x%x subcmd=%u", + __FUNCTION__, mVendor_id, mSubcmd); + } + return res; +} + +void WifiLoggerCommand::unregisterHandler(u32 subCmd) +{ + unregisterVendorHandler(mVendor_id, subCmd); +} + +wifi_error WifiLoggerCommand::timed_wait(u16 wait_time) +{ + struct timespec absTime; + absTime.tv_sec = wait_time; + absTime.tv_nsec = 0; + return mCondition.wait(absTime); +} + +void WifiLoggerCommand::waitForRsp(bool wait) +{ + mWaitforRsp = wait; +} + +/* Function to get Driver memory dump */ +wifi_error wifi_get_driver_memory_dump(wifi_interface_handle iface, + wifi_driver_memory_dump_callbacks callback) +{ + FILE *fp; + size_t fileSize, remaining, readSize; + size_t numRecordsRead; + char *memBuffer = NULL, *buffer = NULL; + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & + WIFI_LOGGER_DRIVER_DUMP_SUPPORTED)) { + ALOGE("%s: Driver memory dump logging feature not supported %x", + __FUNCTION__, info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + /* Open File */ + fp = fopen(DRIVER_MEMDUMP_FILENAME, "r"); + if (fp == NULL) { + ALOGE("Failed to open %s file", DRIVER_MEMDUMP_FILENAME); + return WIFI_ERROR_UNKNOWN; + } + + memBuffer = (char *) malloc(DRIVER_MEMDUMP_MAX_FILESIZE); + if (memBuffer == NULL) { + ALOGE("%s: malloc failed for size %d", __FUNCTION__, + DRIVER_MEMDUMP_MAX_FILESIZE); + fclose(fp); + return WIFI_ERROR_OUT_OF_MEMORY; + } + + /* Read the DRIVER_MEMDUMP_MAX_FILESIZE value at once */ + numRecordsRead = fread(memBuffer, 1, DRIVER_MEMDUMP_MAX_FILESIZE, fp); + if (feof(fp)) + fileSize = numRecordsRead; + else if (numRecordsRead == DRIVER_MEMDUMP_MAX_FILESIZE) { + ALOGE("%s: Reading only first %zu bytes from file", __FUNCTION__, + numRecordsRead); + fileSize = numRecordsRead; + } else { + ALOGE("%s: Read failed for reading at once, ret: %zu. Trying to read in" + "chunks", __FUNCTION__, numRecordsRead); + /* Lets try to read in chunks */ + rewind(fp); + remaining = DRIVER_MEMDUMP_MAX_FILESIZE; + buffer = memBuffer; + fileSize = 0; + while (remaining) { + readSize = 0; + if (remaining >= LOGGER_MEMDUMP_CHUNKSIZE) + readSize = LOGGER_MEMDUMP_CHUNKSIZE; + else + readSize = remaining; + + numRecordsRead = fread(buffer, 1, readSize, fp); + fileSize += numRecordsRead; + if (feof(fp)) + break; + else if (numRecordsRead == readSize) { + remaining -= readSize; + buffer += readSize; + ALOGV("%s: Read successful for size:%zu remaining:%zu", + __FUNCTION__, readSize, remaining); + } else { + ALOGE("%s: Chunk read failed for size:%zu", __FUNCTION__, + readSize); + free(memBuffer); + memBuffer = NULL; + fclose(fp); + return WIFI_ERROR_UNKNOWN; + } + } + } + ALOGV("%s filename: %s fileSize: %zu", __FUNCTION__, DRIVER_MEMDUMP_FILENAME, + fileSize); + /* After successful read, call the callback function*/ + callback.on_driver_memory_dump(memBuffer, fileSize); + + /* free the allocated memory */ + free(memBuffer); + fclose(fp); + return WIFI_SUCCESS; +} + +/* Function to get wake lock stats */ +wifi_error wifi_get_wake_reason_stats(wifi_interface_handle iface, + WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) +{ + int requestId; + wifi_error ret; + WifiLoggerCommand *wifiLoggerCommand; + interface_info *ifaceInfo = getIfaceInfo(iface); + wifi_handle wifiHandle = getWifiHandle(iface); + hal_info *info = getHalInfo(wifiHandle); + + /* Check Supported logger capability */ + if (!(info->supported_logger_feature_set & + WIFI_LOGGER_WAKE_LOCK_SUPPORTED)) { + ALOGE("%s: Wake lock logging feature not supported %x", + __FUNCTION__, info->supported_logger_feature_set); + return WIFI_ERROR_NOT_SUPPORTED; + } + + /* No request id from caller, so generate one and pass it on to the driver. + * Generate it randomly. + */ + requestId = get_requestid(); + + if (!wifi_wake_reason_cnt) { + ALOGE("%s: Invalid buffer provided. Exit.", + __FUNCTION__); + return WIFI_ERROR_INVALID_ARGS; + } + + wifiLoggerCommand = new WifiLoggerCommand( + wifiHandle, + requestId, + OUI_QCA, + QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS); + if (wifiLoggerCommand == NULL) { + ALOGE("%s: Error WifiLoggerCommand NULL", __FUNCTION__); + return WIFI_ERROR_UNKNOWN; + } + + /* Create the NL message. */ + ret = wifiLoggerCommand->create(); + if (ret != WIFI_SUCCESS) + goto cleanup; + + /* Set the interface Id of the message. */ + ret = wifiLoggerCommand->set_iface_id(ifaceInfo->name); + if (ret != WIFI_SUCCESS) + goto cleanup; + + wifiLoggerCommand->getWakeStatsRspParams(wifi_wake_reason_cnt); + + /* Send the msg and wait for a response. */ + ret = wifiLoggerCommand->requestResponse(); + if (ret != WIFI_SUCCESS) + ALOGE("%s: Error %d happened. ", __FUNCTION__, ret); + +cleanup: + delete wifiLoggerCommand; + return ret; +} + +void WifiLoggerCommand::getWakeStatsRspParams( + WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt) +{ + mGetWakeStats = wifi_wake_reason_cnt; +} diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp new file mode 100644 index 0000000..50de781 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp @@ -0,0 +1,2926 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +/* Suppress -Waddress-of-packed-member for new toolchain update. + * Bug: http://b/33566695 + */ +#if __clang_major__ >= 4 +#pragma clang diagnostic ignored "-Waddress-of-packed-member" +#endif + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> +#include <netinet/in.h> +#include <cld80211_lib.h> +#include "wifiloggercmd.h" +#include "wifilogger_event_defs.h" +#include "wifilogger_diag.h" +#include "wifilogger_vendor_tag_defs.h" +#include "pkt_stats.h" +#include <errno.h> +#include "wifi_hal_ctrl.h" + +#define MAX_EVENT_REASON_CODE 1024 +static uint32_t get_le32(const uint8_t *pos) +{ + return pos[0] | (pos[1] << 8) | (pos[2] << 16) | (pos[3] << 24); +} + +#define MAX_CONNECTIVITY_EVENTS 18 // should match the value in wifi_logger.h +static event_remap_t events[MAX_CONNECTIVITY_EVENTS] = { + {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_ASSOCIATION_REQUESTED}, + {WLAN_PE_DIAG_AUTH_COMP_EVENT, WIFI_EVENT_AUTH_COMPLETE}, + {WLAN_PE_DIAG_CONNECTED, WIFI_EVENT_ASSOC_COMPLETE}, + {WLAN_PE_DIAG_AUTH_START_EVENT, WIFI_EVENT_FW_AUTH_STARTED}, + {WLAN_PE_DIAG_ASSOC_START_EVENT, WIFI_EVENT_FW_ASSOC_STARTED}, + {WLAN_PE_DIAG_REASSOC_START_EVENT, WIFI_EVENT_FW_RE_ASSOC_STARTED}, + {WLAN_PE_DIAG_SCAN_REQ_EVENT, WIFI_EVENT_DRIVER_SCAN_REQUESTED}, + {WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND}, + {WLAN_PE_DIAG_SCAN_COMP_EVENT, WIFI_EVENT_DRIVER_SCAN_COMPLETE}, + {WLAN_PE_DIAG_DISASSOC_REQ_EVENT, WIFI_EVENT_DISASSOCIATION_REQUESTED}, + {WLAN_PE_DIAG_ASSOC_REQ_EVENT, WIFI_EVENT_RE_ASSOCIATION_REQUESTED}, + {WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, WIFI_EVENT_ROAM_AUTH_STARTED}, + {WLAN_PE_DIAG_PRE_AUTH_RSP_EVENT, WIFI_EVENT_ROAM_AUTH_COMPLETE}, + {WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT, WIFI_EVENT_ROAM_ASSOC_STARTED}, + {WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, WIFI_EVENT_ROAM_ASSOC_COMPLETE}, + {WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT}, + {WLAN_PE_DIAG_ASSOC_TIMEOUT, WIFI_EVENT_ASSOC_TIMEOUT}, + {WLAN_PE_DIAG_AUTH_TIMEOUT, WIFI_EVENT_AUTH_TIMEOUT}, +}; + +tlv_log* addLoggerTlv(u16 type, u16 length, u8* value, tlv_log *pOutTlv) +{ + + pOutTlv->tag = type; + pOutTlv->length = length; + memcpy(&pOutTlv->value[0], value, length); + + return((tlv_log *)((u8 *)pOutTlv + sizeof(tlv_log) + length)); +} + +int add_reason_code_tag(tlv_log **tlvs, u16 reason_code) +{ + *tlvs = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(u16), + (u8 *)&reason_code, *tlvs); + return (sizeof(tlv_log) + sizeof(u16)); +} + +int add_status_tag(tlv_log **tlvs, int status) +{ + *tlvs = addLoggerTlv(WIFI_TAG_STATUS, sizeof(int), + (u8 *)&status, *tlvs); + return (sizeof(tlv_log) + sizeof(int)); +} + +static wifi_error update_connectivity_ring_buf(hal_info *info, + wifi_ring_buffer_entry *rbe, + u32 size) +{ + struct timeval time; + u32 total_length = size + sizeof(wifi_ring_buffer_entry); + + rbe->entry_size = size; + rbe->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY | + RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + rbe->type = ENTRY_TYPE_CONNECT_EVENT; + gettimeofday(&time,NULL); + rbe->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + /* Write if verbose level and handler are set */ + if (info->rb_infos[CONNECTIVITY_EVENTS_RB_ID].verbose_level >= 1 && + info->on_ring_buffer_data) { + return ring_buffer_write(&info->rb_infos[CONNECTIVITY_EVENTS_RB_ID], + (u8*)rbe, total_length, 1, total_length); + } + + return WIFI_SUCCESS; +} + +#define SCAN_CAP_ENTRY_SIZE 1024 +static wifi_error process_log_extscan_capabilities(hal_info *info, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + wlan_ext_scan_capabilities_payload_type *pScanCapabilities; + wifi_gscan_capabilities gscan_cap; + gscan_capabilities_vendor_data_t cap_vendor_data; + memset(&cap_vendor_data, 0, sizeof(cap_vendor_data)); + + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[SCAN_CAP_ENTRY_SIZE]; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, SCAN_CAP_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + pConnectEvent->event = WIFI_EVENT_G_SCAN_CAPABILITIES; + pTlv = &pConnectEvent->tlvs[0]; + + pScanCapabilities = (wlan_ext_scan_capabilities_payload_type *)buf; + pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, + sizeof(pScanCapabilities->request_id), + (u8 *)&pScanCapabilities->request_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pScanCapabilities->request_id); + + gscan_cap.max_scan_cache_size = + pScanCapabilities->extscan_cache_capabilities.scan_cache_entry_size; + gscan_cap.max_scan_buckets = + pScanCapabilities->extscan_cache_capabilities.max_buckets; + gscan_cap.max_ap_cache_per_scan = + pScanCapabilities->extscan_cache_capabilities.max_bssid_per_scan; + gscan_cap.max_rssi_sample_size = FEATURE_NOT_SUPPORTED; + gscan_cap.max_scan_reporting_threshold = + pScanCapabilities->extscan_cache_capabilities.max_table_usage_threshold; + gscan_cap.max_hotlist_bssids = + pScanCapabilities->extscan_hotlist_monitor_capabilities.max_hotlist_entries; + gscan_cap.max_hotlist_ssids = + pScanCapabilities->extscan_capabilities.num_extscan_hotlist_ssid; + gscan_cap.max_significant_wifi_change_aps = FEATURE_NOT_SUPPORTED; + gscan_cap.max_bssid_history_entries = FEATURE_NOT_SUPPORTED; + gscan_cap.max_number_epno_networks = + pScanCapabilities->extscan_capabilities.num_epno_networks; + gscan_cap.max_number_epno_networks_by_ssid = + pScanCapabilities->extscan_capabilities.num_epno_networks; + gscan_cap.max_number_of_white_listed_ssid = + pScanCapabilities->extscan_capabilities.num_roam_ssid_whitelist; + + pTlv = addLoggerTlv(WIFI_TAG_GSCAN_CAPABILITIES, + sizeof(wifi_gscan_capabilities), + (u8 *)&gscan_cap, pTlv); + tot_len += sizeof(tlv_log) + sizeof(wifi_gscan_capabilities); + + cap_vendor_data.hotlist_mon_table_id = + pScanCapabilities->extscan_hotlist_monitor_capabilities.table_id; + cap_vendor_data.wlan_hotlist_entry_size = + pScanCapabilities->extscan_hotlist_monitor_capabilities.wlan_hotlist_entry_size; + cap_vendor_data.cache_cap_table_id = + pScanCapabilities->extscan_cache_capabilities.table_id; + cap_vendor_data.requestor_id = + pScanCapabilities->extscan_capabilities.requestor_id; + cap_vendor_data.vdev_id = + pScanCapabilities->extscan_capabilities.vdev_id; + cap_vendor_data.num_extscan_cache_tables = + pScanCapabilities->extscan_capabilities.num_extscan_cache_tables; + cap_vendor_data.num_wlan_change_monitor_tables = + pScanCapabilities->extscan_capabilities.num_wlan_change_monitor_tables; + cap_vendor_data.num_hotlist_monitor_tables = + pScanCapabilities->extscan_capabilities.num_hotlist_monitor_tables; + cap_vendor_data.rtt_one_sided_supported = + pScanCapabilities->extscan_capabilities.rtt_one_sided_supported; + cap_vendor_data.rtt_11v_supported = + pScanCapabilities->extscan_capabilities.rtt_11v_supported; + cap_vendor_data.rtt_ftm_supported = + pScanCapabilities->extscan_capabilities.rtt_ftm_supported; + cap_vendor_data.num_extscan_cache_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_cache_capabilities; + cap_vendor_data.num_extscan_wlan_change_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_wlan_change_capabilities; + cap_vendor_data.num_extscan_hotlist_capabilities = + pScanCapabilities->extscan_capabilities.num_extscan_hotlist_capabilities; + cap_vendor_data.num_roam_bssid_blacklist = + pScanCapabilities->extscan_capabilities.num_roam_bssid_blacklist; + cap_vendor_data.num_roam_bssid_preferred_list = + pScanCapabilities->extscan_capabilities.num_roam_bssid_preferred_list; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(gscan_capabilities_vendor_data_t), + (u8 *)&cap_vendor_data, pTlv); + tot_len += sizeof(tlv_log) + sizeof(gscan_capabilities_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write ext scan capabilities event into ring buffer"); + } + return status; +} + +static wifi_error process_bt_coex_scan_event(hal_info *info, + u32 id, u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + pTlv = &pConnectEvent->tlvs[0]; + + if (id == EVENT_WLAN_BT_COEX_BT_SCAN_START) { + wlan_bt_coex_bt_scan_start_payload_type *pBtScanStart; + bt_coex_bt_scan_start_vendor_data_t btScanStartVenData; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_START; + + pBtScanStart = (wlan_bt_coex_bt_scan_start_payload_type *)buf; + btScanStartVenData.scan_type = pBtScanStart->scan_type; + btScanStartVenData.scan_bitmap = pBtScanStart->scan_bitmap; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(bt_coex_bt_scan_start_vendor_data_t), + (u8 *)&btScanStartVenData, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(bt_coex_bt_scan_start_vendor_data_t); + } else if(id == EVENT_WLAN_BT_COEX_BT_SCAN_STOP) { + wlan_bt_coex_bt_scan_stop_payload_type *pBtScanStop; + bt_coex_bt_scan_stop_vendor_data_t btScanStopVenData; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCAN_STOP; + + pBtScanStop = (wlan_bt_coex_bt_scan_stop_payload_type *)buf; + btScanStopVenData.scan_type = pBtScanStop->scan_type; + btScanStopVenData.scan_bitmap = pBtScanStop->scan_bitmap; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(bt_coex_bt_scan_stop_vendor_data_t), + (u8 *)&btScanStopVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(bt_coex_bt_scan_stop_vendor_data_t); + } + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write bt_coex_scan event into ring buffer"); + } + + return status; +} + +static wifi_error process_bt_coex_event(hal_info *info, u32 id, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + u8 link_id, link_state, link_role, link_type = 0, Rsco = 0; + u16 Tsco = 0; + wifi_error status; + bt_coex_hid_vendor_data_t btCoexHidVenData; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + switch (id) { + case EVENT_WLAN_BT_COEX_BT_SCO_START: + { + wlan_bt_coex_bt_sco_start_payload_type *pBtCoexStartPL; + pBtCoexStartPL = (wlan_bt_coex_bt_sco_start_payload_type *)buf; + + link_id = pBtCoexStartPL->link_id; + link_state = pBtCoexStartPL->link_state; + link_role = pBtCoexStartPL->link_role; + link_type = pBtCoexStartPL->link_type; + Tsco = pBtCoexStartPL->Tsco; + Rsco = pBtCoexStartPL->Rsco; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_START; + } + break; + case EVENT_WLAN_BT_COEX_BT_SCO_STOP: + { + wlan_bt_coex_bt_sco_stop_payload_type *pBtCoexStopPL; + pBtCoexStopPL = (wlan_bt_coex_bt_sco_stop_payload_type *)buf; + + link_id = pBtCoexStopPL->link_id; + link_state = pBtCoexStopPL->link_state; + link_role = pBtCoexStopPL->link_role; + link_type = pBtCoexStopPL->link_type; + Tsco = pBtCoexStopPL->Tsco; + Rsco = pBtCoexStopPL->Rsco; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_SCO_STOP; + } + break; + case EVENT_WLAN_BT_COEX_BT_HID_START: + { + wlan_bt_coex_bt_hid_start_payload_type *pBtCoexHidStartPL; + pBtCoexHidStartPL = (wlan_bt_coex_bt_hid_start_payload_type *)buf; + + link_id = pBtCoexHidStartPL->link_id; + link_state = pBtCoexHidStartPL->link_state; + link_role = pBtCoexHidStartPL->link_role; + btCoexHidVenData.Tsniff = pBtCoexHidStartPL->Tsniff; + btCoexHidVenData.attempts = pBtCoexHidStartPL->attempts; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_START; + } + break; + case EVENT_WLAN_BT_COEX_BT_HID_STOP: + { + wlan_bt_coex_bt_hid_stop_payload_type *pBtCoexHidStopPL; + pBtCoexHidStopPL = (wlan_bt_coex_bt_hid_stop_payload_type *)buf; + + link_id = pBtCoexHidStopPL->link_id; + link_state = pBtCoexHidStopPL->link_state; + link_role = pBtCoexHidStopPL->link_role; + btCoexHidVenData.Tsniff = pBtCoexHidStopPL->Tsniff; + btCoexHidVenData.attempts = pBtCoexHidStopPL->attempts; + + pConnectEvent->event = WIFI_EVENT_BT_COEX_BT_HID_STOP; + } + break; + default: + return WIFI_SUCCESS; + } + + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_LINK_ID, sizeof(link_id), &link_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(link_id); + + pTlv = addLoggerTlv(WIFI_TAG_LINK_ROLE, sizeof(link_role), + &link_role, pTlv); + tot_len += sizeof(tlv_log) + sizeof(link_role); + + pTlv = addLoggerTlv(WIFI_TAG_LINK_STATE, sizeof(link_state), + &link_state, pTlv); + tot_len += sizeof(tlv_log) + sizeof(link_state); + + if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_START) || + (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_SCO_STOP)) { + pTlv = addLoggerTlv(WIFI_TAG_LINK_TYPE, sizeof(link_type), + &link_type, pTlv); + tot_len += sizeof(tlv_log) + sizeof(link_type); + + pTlv = addLoggerTlv(WIFI_TAG_TSCO, sizeof(Tsco), (u8 *)&Tsco, pTlv); + tot_len += sizeof(tlv_log) + sizeof(Tsco); + + pTlv = addLoggerTlv(WIFI_TAG_RSCO, sizeof(Rsco), &Rsco, pTlv); + tot_len += sizeof(tlv_log) + sizeof(Rsco); + } else if ((pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_START) || + (pConnectEvent->event == EVENT_WLAN_BT_COEX_BT_HID_STOP)) { + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(bt_coex_hid_vendor_data_t), + (u8 *)&btCoexHidVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(bt_coex_hid_vendor_data_t); + } + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write bt_coex_event into ring buffer"); + } + + return status; +} + +static wifi_error process_extscan_event(hal_info *info, u32 id, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + pTlv = &pConnectEvent->tlvs[0]; + + switch (id) { + case EVENT_WLAN_EXTSCAN_CYCLE_STARTED: + { + ext_scan_cycle_vendor_data_t extScanCycleVenData; + wlan_ext_scan_cycle_started_payload_type *pExtScanCycleStarted; + pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_STARTED; + pExtScanCycleStarted = + (wlan_ext_scan_cycle_started_payload_type *)buf; + pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32), + (u8 *)&pExtScanCycleStarted->scan_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + + extScanCycleVenData.timer_tick = pExtScanCycleStarted->timer_tick; + extScanCycleVenData.scheduled_bucket_mask = + pExtScanCycleStarted->scheduled_bucket_mask; + extScanCycleVenData.scan_cycle_count = + pExtScanCycleStarted->scan_cycle_count; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(ext_scan_cycle_vendor_data_t), + (u8 *)&extScanCycleVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t); + } + break; + case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED: + { + ext_scan_cycle_vendor_data_t extScanCycleVenData; + wlan_ext_scan_cycle_completed_payload_type *pExtScanCycleCompleted; + pConnectEvent->event = WIFI_EVENT_G_SCAN_CYCLE_COMPLETED; + pExtScanCycleCompleted = + (wlan_ext_scan_cycle_completed_payload_type *)buf; + pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, sizeof(u32), + (u8 *)&pExtScanCycleCompleted->scan_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + + extScanCycleVenData.timer_tick = pExtScanCycleCompleted->timer_tick; + extScanCycleVenData.scheduled_bucket_mask = + pExtScanCycleCompleted->scheduled_bucket_mask; + extScanCycleVenData.scan_cycle_count = + pExtScanCycleCompleted->scan_cycle_count; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(ext_scan_cycle_vendor_data_t), + (u8 *)&extScanCycleVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(ext_scan_cycle_vendor_data_t); + } + break; + case EVENT_WLAN_EXTSCAN_BUCKET_STARTED: + { + wlan_ext_scan_bucket_started_payload_type *pExtScanBucketStarted; + u32 bucket_id; + pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_STARTED; + pExtScanBucketStarted = + (wlan_ext_scan_bucket_started_payload_type *)buf; + bucket_id = (u32)pExtScanBucketStarted->bucket_id; + pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32), + (u8 *)&bucket_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + } + break; + case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED: + { + wlan_ext_scan_bucket_completed_payload_type *pExtScanBucketCmpleted; + u32 bucket_id; + pConnectEvent->event = WIFI_EVENT_G_SCAN_BUCKET_COMPLETED; + pExtScanBucketCmpleted = + (wlan_ext_scan_bucket_completed_payload_type *)buf; + bucket_id = (u32)pExtScanBucketCmpleted->bucket_id; + pTlv = addLoggerTlv(WIFI_TAG_BUCKET_ID, sizeof(u32), + (u8 *)&bucket_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + } + break; + case EVENT_WLAN_EXTSCAN_FEATURE_STOP: + { + wlan_ext_scan_feature_stop_payload_type *pExtScanStop; + pConnectEvent->event = WIFI_EVENT_G_SCAN_STOP; + pExtScanStop = (wlan_ext_scan_feature_stop_payload_type *)buf; + pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, + sizeof(pExtScanStop->request_id), + (u8 *)&pExtScanStop->request_id, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(wlan_ext_scan_feature_stop_payload_type); + } + break; + case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE: + { + wlan_ext_scan_results_available_payload_type *pExtScanResultsAvail; + ext_scan_results_available_vendor_data_t extScanResultsAvailVenData; + u32 request_id; + pConnectEvent->event = WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE; + pExtScanResultsAvail = + (wlan_ext_scan_results_available_payload_type *)buf; + request_id = pExtScanResultsAvail->request_id; + pTlv = addLoggerTlv(WIFI_TAG_REQUEST_ID, sizeof(u32), + (u8 *)&request_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + + extScanResultsAvailVenData.table_type = + pExtScanResultsAvail->table_type; + extScanResultsAvailVenData.entries_in_use = + pExtScanResultsAvail->entries_in_use; + extScanResultsAvailVenData.maximum_entries = + pExtScanResultsAvail->maximum_entries; + extScanResultsAvailVenData.scan_count_after_getResults = + pExtScanResultsAvail->scan_count_after_getResults; + extScanResultsAvailVenData.threshold_num_scans = + pExtScanResultsAvail->threshold_num_scans; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(ext_scan_results_available_vendor_data_t), + (u8 *)&extScanResultsAvailVenData, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(ext_scan_results_available_vendor_data_t); + } + break; + } + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write ext_scan event into ring buffer"); + } + + return status; +} + +static wifi_error process_addba_success_event(hal_info *info, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wlan_add_block_ack_success_payload_type *pAddBASuccess; + addba_success_vendor_data_t addBASuccessVenData; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + pAddBASuccess = (wlan_add_block_ack_success_payload_type *)buf; + + addBASuccessVenData.ucBaTid = pAddBASuccess->ucBaTid; + addBASuccessVenData.ucBaBufferSize = pAddBASuccess->ucBaBufferSize; + addBASuccessVenData.ucBaSSN = pAddBASuccess->ucBaSSN; + addBASuccessVenData.fInitiator = pAddBASuccess->fInitiator; + + pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE; + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBASuccess->ucBaPeerMac), + (u8 *)pAddBASuccess->ucBaPeerMac, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pAddBASuccess->ucBaPeerMac); + + tot_len += add_status_tag(&pTlv, (int)ADDBA_SUCCESS); + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(addba_success_vendor_data_t), + (u8 *)&addBASuccessVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(addba_success_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write addba event into ring buffer"); + } + + return status; +} + +static wifi_error process_addba_failed_event(hal_info *info, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wlan_add_block_ack_failed_payload_type *pAddBAFailed; + addba_failed_vendor_data_t addBAFailedVenData; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + pAddBAFailed = (wlan_add_block_ack_failed_payload_type *)buf; + addBAFailedVenData.ucBaTid = pAddBAFailed->ucBaTid; + addBAFailedVenData.fInitiator = pAddBAFailed->fInitiator; + + pConnectEvent->event = WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE; + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_ADDR, sizeof(pAddBAFailed->ucBaPeerMac), + (u8 *)pAddBAFailed->ucBaPeerMac, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pAddBAFailed->ucBaPeerMac); + + tot_len += add_status_tag(&pTlv, (int)ADDBA_FAILURE); + + tot_len += add_reason_code_tag(&pTlv, (u16)pAddBAFailed->ucReasonCode); + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(addba_failed_vendor_data_t), + (u8 *)&addBAFailedVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(addba_failed_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write addba event into ring buffer"); + } + + return status; +} + +static wifi_error process_roam_event(hal_info *info, u32 id, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + switch (id) + { + case EVENT_WLAN_ROAM_SCAN_STARTED: + { + wlan_roam_scan_started_payload_type *pRoamScanStarted; + roam_scan_started_vendor_data_t roamScanStartedVenData; + pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_STARTED; + pRoamScanStarted = (wlan_roam_scan_started_payload_type *)buf; + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, + sizeof(pRoamScanStarted->scan_id), + (u8 *)&pRoamScanStarted->scan_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamScanStarted->scan_id); + roamScanStartedVenData.roam_scan_flags = + pRoamScanStarted->roam_scan_flags; + roamScanStartedVenData.cur_rssi = pRoamScanStarted->cur_rssi; + memcpy(roamScanStartedVenData.scan_params, + pRoamScanStarted->scan_params, + sizeof(roamScanStartedVenData.scan_params)); + memcpy(roamScanStartedVenData.scan_channels, + pRoamScanStarted->scan_channels, + sizeof(roamScanStartedVenData.scan_channels)); + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(roam_scan_started_vendor_data_t), + (u8 *)&roamScanStartedVenData, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(roam_scan_started_vendor_data_t); + } + break; + case EVENT_WLAN_ROAM_SCAN_COMPLETE: + { + wlan_roam_scan_complete_payload_type *pRoamScanComplete; + roam_scan_complete_vendor_data_t roamScanCompleteVenData; + pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_COMPLETE; + pRoamScanComplete = (wlan_roam_scan_complete_payload_type *)buf; + pTlv = &pConnectEvent->tlvs[0]; + + pTlv = addLoggerTlv(WIFI_TAG_SCAN_ID, + sizeof(pRoamScanComplete->scan_id), + (u8 *)&pRoamScanComplete->scan_id, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamScanComplete->scan_id); + + roamScanCompleteVenData.reason = pRoamScanComplete->reason; + roamScanCompleteVenData.completion_flags = + pRoamScanComplete->completion_flags; + roamScanCompleteVenData.num_candidate = + pRoamScanComplete->num_candidate; + roamScanCompleteVenData.flags = pRoamScanComplete->flags; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(roam_scan_complete_vendor_data_t), + (u8 *)&roamScanCompleteVenData, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(roam_scan_complete_vendor_data_t); + } + break; + case EVENT_WLAN_ROAM_CANDIDATE_FOUND: + { + wlan_roam_candidate_found_payload_type *pRoamCandidateFound; + roam_candidate_found_vendor_data_t roamCandidateFoundVendata; + memset(&roamCandidateFoundVendata, 0, + sizeof(roamCandidateFoundVendata)); + pConnectEvent->event = WIFI_EVENT_ROAM_CANDIDATE_FOUND; + pRoamCandidateFound = (wlan_roam_candidate_found_payload_type *)buf; + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_CHANNEL, + sizeof(pRoamCandidateFound->channel), + (u8 *)&pRoamCandidateFound->channel, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->channel); + + pTlv = addLoggerTlv(WIFI_TAG_RSSI, + sizeof(pRoamCandidateFound->rssi), + (u8 *)&pRoamCandidateFound->rssi, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->rssi); + + pTlv = addLoggerTlv(WIFI_TAG_BSSID, + sizeof(pRoamCandidateFound->bssid), + (u8 *)pRoamCandidateFound->bssid, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->bssid); + + pTlv = addLoggerTlv(WIFI_TAG_SSID, + sizeof(pRoamCandidateFound->ssid), + (u8 *)pRoamCandidateFound->ssid, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pRoamCandidateFound->ssid); + + roamCandidateFoundVendata.auth_mode = + pRoamCandidateFound->auth_mode; + roamCandidateFoundVendata.ucast_cipher = + pRoamCandidateFound->ucast_cipher; + roamCandidateFoundVendata.mcast_cipher = + pRoamCandidateFound->mcast_cipher; + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(roam_candidate_found_vendor_data_t), + (u8 *)&roamCandidateFoundVendata, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(roam_candidate_found_vendor_data_t); + } + break; + case EVENT_WLAN_ROAM_SCAN_CONFIG: + { + wlan_roam_scan_config_payload_type *pRoamScanConfig; + roam_scan_config_vendor_data_t roamScanConfigVenData; + + pConnectEvent->event = WIFI_EVENT_ROAM_SCAN_CONFIG; + pRoamScanConfig = (wlan_roam_scan_config_payload_type *)buf; + + pTlv = &pConnectEvent->tlvs[0]; + + roamScanConfigVenData.flags = pRoamScanConfig->flags; + memcpy(roamScanConfigVenData.roam_scan_config, + pRoamScanConfig->roam_scan_config, + sizeof(roamScanConfigVenData.roam_scan_config)); + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(roam_scan_config_vendor_data_t), + (u8 *)&roamScanConfigVenData, pTlv); + tot_len += sizeof(tlv_log) + + sizeof(roam_scan_config_vendor_data_t); + } + break; + } + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write roam event into ring buffer"); + } + + return status; +} + +wifi_error process_firmware_prints(hal_info *info, u8 *buf, u16 length) +{ + wifi_ring_buffer_entry rb_entry_hdr; + struct timeval time; + wifi_error status; + + rb_entry_hdr.entry_size = length; + rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + rb_entry_hdr.type = ENTRY_TYPE_DATA; + gettimeofday(&time, NULL); + rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + /* Write if verbose and handler is set */ + if (info->rb_infos[FIRMWARE_PRINTS_RB_ID].verbose_level >= 1 && + info->on_ring_buffer_data) { + /* Write header and payload separately to avoid + * complete payload memcpy */ + if (sizeof(wifi_ring_buffer_entry) + length > 2000) { + ALOGE("Invalid length of buffer wifi_ring_buffer_entry size: %zu length %u ",sizeof(wifi_ring_buffer_entry), length); + return WIFI_ERROR_UNKNOWN; + } + status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID], + (u8*)&rb_entry_hdr, + sizeof(wifi_ring_buffer_entry), + 0, + sizeof(wifi_ring_buffer_entry) + length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write firmware prints rb header %d", status); + return status; + } + status = ring_buffer_write(&info->rb_infos[FIRMWARE_PRINTS_RB_ID], + buf, length, 1, length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write firmware prints rb payload %d", status); + return status; + } + } + + return WIFI_SUCCESS; +} + +static wifi_error process_beacon_received_event(hal_info *info, + u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wlan_beacon_received_payload_type *pBeaconRcvd; + u32 rssi; + wifi_error status; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + pBeaconRcvd = (wlan_beacon_received_payload_type *)buf; + + pConnectEvent->event = WIFI_EVENT_BEACON_RECEIVED; + pTlv = &pConnectEvent->tlvs[0]; + + pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pBeaconRcvd->bssid), + (u8 *)pBeaconRcvd->bssid, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pBeaconRcvd->bssid); + + rssi = get_rssi(pBeaconRcvd->beacon_rssi); + pTlv = addLoggerTlv(WIFI_TAG_RSSI, + sizeof(rssi), (u8 *)&rssi, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pBeaconRcvd->beacon_rssi); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write addba event into ring buffer"); + } + + return status; +} + +static wifi_error process_fw_diag_msg(hal_info *info, u8* buf, u32 length) +{ + u32 count = 0, id; + u32 payloadlen = 0; + u16 hdr_size = 0; + wifi_error status; + fw_diag_msg_fixed_hdr_t *diag_msg_fixed_hdr; + fw_diag_msg_hdr_t *diag_msg_hdr; + fw_diag_msg_hdr_v2_t *diag_msg_hdr_v2; + u8 *payload = NULL; + + buf += 4; + length -= 4; + + while ((info && !info->clean_up) + && (length > (count + sizeof(fw_diag_msg_fixed_hdr_t)))) { + diag_msg_fixed_hdr = (fw_diag_msg_fixed_hdr_t *)(buf + count); + + if (diag_msg_fixed_hdr->diag_event_type > WLAN_DIAG_TYPE_LEGACY_MSG) { + hdr_size = sizeof(fw_diag_msg_hdr_v2_t); + } else { + hdr_size = sizeof(fw_diag_msg_hdr_t); + } + + if ((count + hdr_size) > length) + { + ALOGE("process_fw_diag_msg (%d) - possible buffer over access, length=%d count=%d hdr_size=%d", + diag_msg_fixed_hdr->diag_event_type, length, count, hdr_size); + return WIFI_ERROR_UNKNOWN; + } + + switch (diag_msg_fixed_hdr->diag_event_type) { + case WLAN_DIAG_TYPE_EVENT: + case WLAN_DIAG_TYPE_EVENT_V2: + { + if (WLAN_DIAG_TYPE_EVENT == + diag_msg_fixed_hdr->diag_event_type) { + diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr->diag_id; + payloadlen = diag_msg_hdr->u.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_t); + payload = diag_msg_hdr->payload; + } else { + diag_msg_hdr_v2 = + (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr_v2->diag_id; + payloadlen = diag_msg_hdr_v2->u.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_v2_t); + payload = diag_msg_hdr_v2->payload; + } + if ((count + hdr_size + payloadlen) > length) { + ALOGE("WLAN_DIAG_TYPE_EVENT - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d", + length, count, hdr_size, payloadlen); + return WIFI_ERROR_UNKNOWN; + } + + switch (id) { + case EVENT_WLAN_BT_COEX_BT_SCO_START: + case EVENT_WLAN_BT_COEX_BT_SCO_STOP: + case EVENT_WLAN_BT_COEX_BT_HID_START: + case EVENT_WLAN_BT_COEX_BT_HID_STOP: + status = process_bt_coex_event(info, id, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process bt_coex event"); + return status; + } + break; + case EVENT_WLAN_BT_COEX_BT_SCAN_START: + case EVENT_WLAN_BT_COEX_BT_SCAN_STOP: + status = process_bt_coex_scan_event(info, id, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process bt_coex_scan event"); + return status; + } + break; + case EVENT_WLAN_EXTSCAN_CYCLE_STARTED: + case EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED: + case EVENT_WLAN_EXTSCAN_BUCKET_STARTED: + case EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED: + case EVENT_WLAN_EXTSCAN_FEATURE_STOP: + case EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE: + status = process_extscan_event(info, id, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process extscan event"); + return status; + } + break; + case EVENT_WLAN_ROAM_SCAN_STARTED: + case EVENT_WLAN_ROAM_SCAN_COMPLETE: + case EVENT_WLAN_ROAM_CANDIDATE_FOUND: + case EVENT_WLAN_ROAM_SCAN_CONFIG: + status = process_roam_event(info, id, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process roam event"); + return status; + } + break; + case EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS: + status = process_addba_success_event(info, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process addba success event"); + return status; + } + break; + case EVENT_WLAN_ADD_BLOCK_ACK_FAILED: + status = process_addba_failed_event(info, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process addba failed event"); + return status; + } + break; + case EVENT_WLAN_BEACON_EVENT: + status = process_beacon_received_event(info, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process beacon received event"); + return status; + } + break; + default: + return WIFI_SUCCESS; + } + } + break; + case WLAN_DIAG_TYPE_LOG: + case WLAN_DIAG_TYPE_LOG_V2: + { + if (WLAN_DIAG_TYPE_LOG == diag_msg_fixed_hdr->diag_event_type) { + diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr->diag_id; + payloadlen = diag_msg_hdr->u.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_t); + payload = diag_msg_hdr->payload; + } else { + diag_msg_hdr_v2 = (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr_v2->diag_id; + payloadlen = diag_msg_hdr_v2->u.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_v2_t); + payload = diag_msg_hdr_v2->payload; + } + if ((count + hdr_size + payloadlen) > length) { + ALOGE("WLAN_DIAG_TYPE_LOG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d", + length, count, hdr_size, payloadlen); + return WIFI_ERROR_UNKNOWN; + } + + switch (id) { + case LOG_WLAN_EXTSCAN_CAPABILITIES: + status = process_log_extscan_capabilities(info, + payload, + payloadlen); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to process extscan capabilities"); + return status; + } + break; + default: + break; + } + } + break; + case WLAN_DIAG_TYPE_MSG: + diag_msg_hdr = (fw_diag_msg_hdr_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr->diag_id; + /* Length field is only one byte for WLAN_DIAG_TYPE_MSG */ + payloadlen = diag_msg_hdr->u.msg_hdr.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_t); + payload = diag_msg_hdr->payload; + if ((count + hdr_size + payloadlen) > length) { + ALOGE("WLAN_DIAG_TYPE_MSG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d", + length, count, hdr_size, payloadlen); + return WIFI_ERROR_UNKNOWN; + } + process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr, + payloadlen + hdr_size); + break; + case WLAN_DIAG_TYPE_MSG_V2: + diag_msg_hdr_v2 = (fw_diag_msg_hdr_v2_t *)diag_msg_fixed_hdr; + id = diag_msg_hdr_v2->diag_id; + /* Length field is only one byte for WLAN_DIAG_TYPE_MSG_V2 */ + payloadlen = diag_msg_hdr_v2->u.msg_hdr.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_v2_t); + payload = diag_msg_hdr_v2->payload; + if ((count + hdr_size + payloadlen) > length) { + ALOGE("WLAN_DIAG_TYPE_MSG_V2 - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d", + length, count, hdr_size, payloadlen); + return WIFI_ERROR_UNKNOWN; + } + process_firmware_prints(info, (u8 *)diag_msg_fixed_hdr, + payloadlen + hdr_size); + break; + case WLAN_DIAG_TYPE_CONFIG: + { + /* Base timestamp is part of this diag type */ + diag_msg_hdr = (fw_diag_msg_hdr_t *) diag_msg_fixed_hdr; + id = diag_msg_hdr->diag_id; + payload = diag_msg_hdr->payload; + payloadlen = diag_msg_hdr->u.payload_len; + hdr_size = sizeof(fw_diag_msg_hdr_t); + if ((count + hdr_size + payloadlen) > length) { + ALOGE("WLAN_DIAG_TYPE_CONFIG - possible buffer over access, length=%d count=%d hdr_size=%d payload len=%d", + length, count, hdr_size, payloadlen); + return WIFI_ERROR_UNKNOWN; + } + process_firmware_prints(info, (u8 *)diag_msg_hdr, + payloadlen + hdr_size); + } + break; + default: + return WIFI_SUCCESS; + } + count += payloadlen + hdr_size; + } + return WIFI_SUCCESS; +} + +static wifi_error remap_event(int in_event, int *out_event) +{ + int i = 0; + while (i < MAX_CONNECTIVITY_EVENTS) { + if (events[i].q_event == in_event) { + *out_event = events[i].g_event; + return WIFI_SUCCESS; + } + i++; + } + return WIFI_ERROR_UNKNOWN; +} + +static wifi_error process_wlan_pe_event(hal_info *info, u8* buf, int length) +{ + wlan_pe_event_t *pWlanPeEvent; + pe_event_vendor_data_t peEventVenData; + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + tlv_log *pTlv; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + u8 out_buf[RING_BUF_ENTRY_SIZE]; + wifi_error status; + + pWlanPeEvent = (wlan_pe_event_t *)buf; + + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + status = remap_event(pWlanPeEvent->event_type, + (int *)&pConnectEvent->event); + if (status != WIFI_SUCCESS) + return status; + + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_BSSID, sizeof(pWlanPeEvent->bssid), + (u8 *)pWlanPeEvent->bssid, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->bssid); + + tot_len += add_status_tag(&pTlv, (int)pWlanPeEvent->status); + + pTlv = addLoggerTlv(WIFI_TAG_REASON_CODE, sizeof(pWlanPeEvent->reason_code), + (u8 *)&pWlanPeEvent->reason_code, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pWlanPeEvent->reason_code); + + peEventVenData.sme_state = pWlanPeEvent->sme_state; + peEventVenData.mlm_state = pWlanPeEvent->mlm_state; + + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(pe_event_vendor_data_t), + (u8 *)&peEventVenData, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pe_event_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write pe event into ring buffer"); + } + + return status; +} + +static wifi_error process_wlan_eapol_event(hal_info *info, u8* buf, int length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wlan_eapol_event_t *pWlanEapolEvent; + wifi_ring_buffer_entry *pRingBufferEntry; + u8 out_buf[RING_BUF_ENTRY_SIZE]; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + tlv_log *pTlv; + u32 eapol_msg_type = 0; + wifi_error status; + + pWlanEapolEvent = (wlan_eapol_event_t *)buf; + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + if (pWlanEapolEvent->event_sub_type == + WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED) + pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED; + else + pConnectEvent->event = WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED; + + pTlv = &pConnectEvent->tlvs[0]; + + if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M1_MASK) + eapol_msg_type = 1; + else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M2_MASK) + eapol_msg_type = 2; + else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M3_MASK) + eapol_msg_type = 3; + else if ((pWlanEapolEvent->eapol_key_info & EAPOL_MASK) == EAPOL_M4_MASK) + eapol_msg_type = 4; + else + ALOGI("Unknown EAPOL message type \n"); + pTlv = addLoggerTlv(WIFI_TAG_EAPOL_MESSAGE_TYPE, sizeof(u32), + (u8 *)&eapol_msg_type, pTlv); + tot_len += sizeof(tlv_log) + sizeof(u32); + pTlv = addLoggerTlv(WIFI_TAG_ADDR1, sizeof(pWlanEapolEvent->dest_addr), + (u8 *)pWlanEapolEvent->dest_addr, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->dest_addr); + pTlv = addLoggerTlv(WIFI_TAG_ADDR2, sizeof(pWlanEapolEvent->src_addr), + (u8 *)pWlanEapolEvent->src_addr, pTlv); + tot_len += sizeof(tlv_log) + sizeof(pWlanEapolEvent->src_addr); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write eapol event into ring buffer"); + } + + return status; +} + +static wifi_error process_wakelock_event(hal_info *info, u8* buf, int length) +{ + wlan_wake_lock_event_t *pWlanWakeLockEvent; + wake_lock_event *pWakeLockEvent; + wifi_power_event *pPowerEvent; + tlv_log *pTlv; + wifi_ring_buffer_entry *pRingBufferEntry; + u16 len_ring_buffer_entry; + struct timeval time; + wifi_error status; + u8 wl_ring_buffer[RING_BUF_ENTRY_SIZE]; + u16 entry_size; + + pWlanWakeLockEvent = (wlan_wake_lock_event_t *)(buf); + entry_size = sizeof(wifi_power_event) + + sizeof(tlv_log) + + sizeof(wake_lock_event) + + pWlanWakeLockEvent->name_len + 1; + len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + entry_size; + + if (len_ring_buffer_entry > RING_BUF_ENTRY_SIZE) { + pRingBufferEntry = (wifi_ring_buffer_entry *)malloc( + len_ring_buffer_entry); + if (pRingBufferEntry == NULL) { + ALOGE("%s: Failed to allocate memory", __FUNCTION__); + return WIFI_ERROR_OUT_OF_MEMORY; + } + } else { + pRingBufferEntry = (wifi_ring_buffer_entry *)wl_ring_buffer; + } + + pPowerEvent = (wifi_power_event *)(pRingBufferEntry + 1); + pPowerEvent->event = WIFI_TAG_WAKE_LOCK_EVENT; + + pTlv = &pPowerEvent->tlvs[0]; + pTlv->tag = WIFI_TAG_WAKE_LOCK_EVENT; + pTlv->length = sizeof(wake_lock_event) + + pWlanWakeLockEvent->name_len + 1; + + pWakeLockEvent = (wake_lock_event *)pTlv->value; + pWakeLockEvent->status = pWlanWakeLockEvent->status; + pWakeLockEvent->reason = pWlanWakeLockEvent->reason; + memcpy(pWakeLockEvent->name, pWlanWakeLockEvent->name, + pWlanWakeLockEvent->name_len); + + pRingBufferEntry->entry_size = entry_size; + pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY | + RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + pRingBufferEntry->type = ENTRY_TYPE_POWER_EVENT; + gettimeofday(&time, NULL); + pRingBufferEntry->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + /* Write if verbose and handler is set */ + if (info->rb_infos[POWER_EVENTS_RB_ID].verbose_level >= 1 && + info->on_ring_buffer_data) { + status = ring_buffer_write(&info->rb_infos[POWER_EVENTS_RB_ID], + (u8*)pRingBufferEntry, + len_ring_buffer_entry, + 1, + len_ring_buffer_entry); + } else { + status = WIFI_SUCCESS; + } + + if ((u8 *)pRingBufferEntry != wl_ring_buffer) { + ALOGI("Message with more than RING_BUF_ENTRY_SIZE"); + free(pRingBufferEntry); + } + + return status; +} + +static void process_wlan_log_complete_event(hal_info *info, + u8* buf, + int length) +{ + wlan_log_complete_event_t *lfd_event; + + ALOGV("Received log completion event from driver"); + lfd_event = (wlan_log_complete_event_t *)buf; + + push_out_all_ring_buffers(info); + + if (lfd_event->is_fatal == WLAN_LOG_TYPE_FATAL) { + ALOGE("Received fatal event, sending alert"); + send_alert(info, lfd_event->reason_code); + } +} + +static void process_wlan_data_stall_event(hal_info *info, + u8* buf, + int length) +{ + wlan_data_stall_event_t *event; + int reason_code = 0; + + ALOGV("Received Data Stall Event from Driver"); + event = (wlan_data_stall_event_t *)buf; + ALOGE("Received Data Stall event, sending alert %d", event->reason); + if(event->reason >= MAX_EVENT_REASON_CODE) + reason_code = 0; + else + reason_code = event->reason; + + send_alert(info, DATA_STALL_OFFSET_REASON_CODE + reason_code); +} + +static void process_wlan_low_resource_failure(hal_info *info, + u8* buf, + u16 length) +{ + wifi_ring_buffer_driver_connectivity_event *pConnectEvent; + wlan_low_resource_failure_event_t *pWlanResourceEvent; + resource_failure_vendor_data_t cap_vendor_data; + wifi_ring_buffer_entry *pRingBufferEntry; + u8 out_buf[RING_BUF_ENTRY_SIZE]; + int tot_len = sizeof(wifi_ring_buffer_driver_connectivity_event); + tlv_log *pTlv; + wifi_error status; + + pWlanResourceEvent = (wlan_low_resource_failure_event_t *)buf; + pRingBufferEntry = (wifi_ring_buffer_entry *)&out_buf[0]; + memset(pRingBufferEntry, 0, RING_BUF_ENTRY_SIZE); + pConnectEvent = (wifi_ring_buffer_driver_connectivity_event *) + (pRingBufferEntry + 1); + + pConnectEvent->event = WIFI_EVENT_MEM_ALLOC_FAILURE; + memset(&cap_vendor_data, 0, sizeof(resource_failure_vendor_data_t)); + + if (length > sizeof(resource_failure_vendor_data_t)) { + ALOGE("Received resource failure event of size : %d, whereas expected" + " size is <= %zu bytes", length, + sizeof(resource_failure_vendor_data_t)); + return; + } + memcpy(&cap_vendor_data, pWlanResourceEvent, length); + + pTlv = &pConnectEvent->tlvs[0]; + pTlv = addLoggerTlv(WIFI_TAG_VENDOR_SPECIFIC, + sizeof(resource_failure_vendor_data_t), + (u8 *)&cap_vendor_data, pTlv); + tot_len += sizeof(tlv_log) + sizeof(resource_failure_vendor_data_t); + + status = update_connectivity_ring_buf(info, pRingBufferEntry, tot_len); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write resource failure event into ring buffer"); + } +} + +static wifi_error update_stats_to_ring_buf(hal_info *info, + u8 *rb_entry, u32 size) +{ + int num_records = 1; + wifi_ring_buffer_entry *pRingBufferEntry = + (wifi_ring_buffer_entry *)rb_entry; + struct timeval time; + + pRingBufferEntry->entry_size = size - sizeof(wifi_ring_buffer_entry); + pRingBufferEntry->flags = RING_BUFFER_ENTRY_FLAGS_HAS_BINARY | + RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + pRingBufferEntry->type = ENTRY_TYPE_PKT; + gettimeofday(&time,NULL); + pRingBufferEntry->timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + // Write if verbose and handler is set + if ((info->rb_infos[PKT_STATS_RB_ID].verbose_level >= VERBOSE_DEBUG_PROBLEM) + && info->on_ring_buffer_data) { + ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID], + (u8*)pRingBufferEntry, + size, + num_records, + size); + } + + return WIFI_SUCCESS; +} + +static u8 cck_ratecode_mapping(u8 rate) +{ + u8 rate_code = 0; + + switch (rate) { + case 0x1: + rate_code = 0x3; + break; + case 0x2: + case 0x5: + rate_code = 0x2; + break; + case 0x3: + case 0x6: + rate_code = 0x1; + break; + case 0x4: + case 0x7: + rate_code = 0x0; + break; + } + return rate_code; +} + +static u8 ofdm_ratecode_mapping(u8 rate) +{ + u8 rate_code = 0; + + rate_code = rate - 8; + return rate_code; +} + +static u16 get_rate_v1(u16 mcs_r) +{ + MCS mcs; + int index = 0; + u16 tx_rate = 0; + u8 nss; + + mcs.mcs = mcs_r; + nss = mcs.mcs_s.nss + 1; + + switch (mcs.mcs_s.preamble) { + case WIFI_HW_RATECODE_PREAM_OFDM: + for (index = 0; index < MAX_OFDM_MCS_IDX; index++) { + if ((mcs.mcs_s.rate & 0xF) == index) + tx_rate = (u16) ofdm_mcs_nss1[index].ofdm_rate[mcs.mcs_s.short_gi] / 1000; + } + break; + case WIFI_HW_RATECODE_PREAM_CCK: + for (index = 0; index < MAX_CCK_MCS_IDX; index++) { + if ((mcs.mcs_s.rate & 0xF) == index) + tx_rate = (u16) cck_mcs_nss1[index].cck_rate[mcs.mcs_s.short_gi] / 1000; + } + break; + case WIFI_HW_RATECODE_PREAM_HT: + if (nss == 1) { + for (index = 0; index < MAX_HT_MCS_IDX; index++) { + if (mcs.mcs_s.rate == index) { + if (mcs.mcs_s.bw == BW_20MHZ) + tx_rate = (u16) mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_40MHZ) + tx_rate = (u16) mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + } + } + } else if (nss == 2) { + for (index = 0; index < MAX_HT_MCS_IDX; index++) { + if (mcs.mcs_s.rate == index) { + if (mcs.mcs_s.bw == BW_20MHZ) + tx_rate = (u16) mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_40MHZ) + tx_rate = (u16) mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + } + } + } else { + ALOGE("Unexpected nss %d", nss); + } + break; + case WIFI_HW_RATECODE_PREAM_VHT: + if (nss == 1) { + for (index = 0; index < MAX_VHT_MCS_IDX; index++) { + if (mcs.mcs_s.rate == index) { + if (mcs.mcs_s.bw == BW_20MHZ) + tx_rate = (u16) vht_mcs_nss1[index].ht20_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_40MHZ) + tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_80MHZ) + tx_rate = (u16) vht_mcs_nss1[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + } + } + } else if (nss == 2) { + for (index = 0; index < MAX_VHT_MCS_IDX; index++) { + if (mcs.mcs_s.rate == index) { + if (mcs.mcs_s.bw == BW_20MHZ) + tx_rate = (u16) vht_mcs_nss2[index].ht20_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_40MHZ) + tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + if (mcs.mcs_s.bw == BW_80MHZ) + tx_rate = (u16) vht_mcs_nss2[index].ht40_rate[mcs.mcs_s.short_gi] / 10; + } + } + } else { + ALOGE("Unexpected nss %d", nss); + } + break; + default: + ALOGE("Unexpected preamble %d", mcs.mcs_s.preamble); + } + return tx_rate; +} + +static u16 get_rate(u16 mcs_r) +{ + u16 tx_rate = 0; + MCS mcs; + static u16 rate_lookup[][8] = {{96, 48, 24, 12, 108, 72, 36, 18}, + {22, 11, 4, 2, 22, 11, 4, 0}}; + static u16 MCS_rate_lookup_ht[][8] = + {{ 13, 14, 27, 30, 59, 65, 117, 130}, + { 26, 29, 54, 60, 117, 130, 234, 260}, + { 39, 43, 81, 90, 176, 195, 351, 390}, + { 52, 58, 108, 120, 234, 260, 468, 520}, + { 78, 87, 162, 180, 351, 390, 702, 780}, + {104, 116, 216, 240, 468, 520, 936, 1040}, + {117, 130, 243, 270, 527, 585, 1053, 1170}, + {130, 144, 270, 300, 585, 650, 1170, 1300}, + {156, 173, 324, 360, 702, 780, 1404, 1560}, + { 0, 0, 360, 400, 780, 867, 1560, 1733}, + { 26, 29, 54, 60, 117, 130, 234, 260}, + { 52, 58, 108, 120, 234, 260, 468, 520}, + { 78, 87, 162, 180, 351, 390, 702, 780}, + {104, 116, 216, 240, 468, 520, 936, 1040}, + {156, 173, 324, 360, 702, 780, 1404, 1560}, + {208, 231, 432, 480, 936,1040, 1872, 2080}, + {234, 261, 486, 540,1053,1170, 2106, 2340}, + {260, 289, 540, 600,1170,1300, 2340, 2600}, + {312, 347, 648, 720,1404,1560, 2808, 3120}, + { 0, 0, 720, 800,1560,1733, 3120, 3467}}; + + mcs.mcs = mcs_r; + if ((mcs.mcs_s.preamble <= WL_PREAMBLE_VHT) && (mcs.mcs_s.rate < 10)) { + switch(mcs.mcs_s.preamble) + { + case WL_PREAMBLE_CCK: + case WL_PREAMBLE_OFDM: + if(mcs.mcs_s.rate<8) { + tx_rate = rate_lookup [mcs.mcs_s.preamble][mcs.mcs_s.rate]; + if (mcs.mcs_s.nss) + tx_rate *=2; + } else { + ALOGE("Unexpected rate value"); + } + break; + case WL_PREAMBLE_HT: + if(mcs.mcs_s.rate<8) { + if (!mcs.mcs_s.nss) + tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate] + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; + else + tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate] + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; + } else { + ALOGE("Unexpected HT mcs.mcs_s index"); + } + break; + case WL_PREAMBLE_VHT: + if (!mcs.mcs_s.nss) + tx_rate = MCS_rate_lookup_ht[mcs.mcs_s.rate] + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; + else + tx_rate = MCS_rate_lookup_ht[10+mcs.mcs_s.rate] + [2*mcs.mcs_s.bw+mcs.mcs_s.short_gi]; + break; + default: + ALOGE("Unexpected preamble"); + } + } + return tx_rate; +} + +static wifi_error populate_rx_aggr_stats(hal_info *info) +{ + wifi_error status; + wifi_ring_buffer_entry *pRingBufferEntry = info->rx_aggr_pkts; + wifi_ring_per_packet_status_entry *pps_entry; + u32 index = 0; + + while (!info->clean_up && (index < info->rx_buf_size_occupied)) { + pps_entry = (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + pps_entry->MCS = info->aggr_stats.RxMCS.mcs; + pps_entry->last_transmit_rate = info->aggr_stats.last_transmit_rate; + pps_entry->rssi = info->aggr_stats.rssi; + pps_entry->firmware_entry_timestamp = info->aggr_stats.timestamp; + pps_entry->tid = info->aggr_stats.tid; + + index += pRingBufferEntry->entry_size; + status = update_stats_to_ring_buf(info, (u8 *)pRingBufferEntry, + pRingBufferEntry->entry_size); + + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write Rx stats into the ring buffer"); + return status; + } + /* update_stats_to_ring_buf() modifies the size. Update the same again + * here by adding sizeof(wifi_ring_buffer_entry) to continue parsing + */ + pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)pRingBufferEntry + + sizeof(wifi_ring_buffer_entry) + + pRingBufferEntry->entry_size); + } + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied); + info->rx_buf_size_occupied = 0; + + return WIFI_SUCCESS; +} + +static wifi_error parse_rx_stats_v2(hal_info *info, u8 *buf, u16 size) +{ + wifi_error status = WIFI_SUCCESS; + rb_pkt_stats_t_v1 *rx_stats_rcvd = (rb_pkt_stats_t_v1 *)buf; + wifi_ring_buffer_entry *pRingBufferEntry; + u32 len_ring_buffer_entry = 0; + + if (size < sizeof(rb_pkt_stats_t)) { + ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size); + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied); + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + info->rx_buf_size_occupied = 0; + return WIFI_ERROR_UNKNOWN; + } + + len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry) + + RX_HTT_HDR_STATUS_LEN_V1; + + if (len_ring_buffer_entry + info->rx_buf_size_occupied + > info->rx_buf_size_allocated) { + wifi_ring_buffer_entry *temp; + temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts, + len_ring_buffer_entry + info->rx_buf_size_occupied); + if (temp == NULL) { + ALOGE("%s: Failed to reallocate memory", __FUNCTION__); + free(info->rx_aggr_pkts); + info->rx_aggr_pkts = NULL; + return WIFI_ERROR_OUT_OF_MEMORY; + } + info->rx_aggr_pkts = temp; + memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0, + len_ring_buffer_entry + info->rx_buf_size_occupied + - info->rx_buf_size_allocated); + info->rx_buf_size_allocated = + len_ring_buffer_entry + info->rx_buf_size_occupied; + } + + pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts + + info->rx_buf_size_occupied); + + info->rx_buf_size_occupied += len_ring_buffer_entry; + + /* Fill size of the entry in rb entry which can be used while populating + * the data. Actual size that needs to be sent to ring buffer is only pps + * entry size + */ + pRingBufferEntry->entry_size = len_ring_buffer_entry; + wifi_ring_per_packet_status_entry *rb_pkt_stats = + (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry)); + + /* Peer tx packet and it is an Rx packet for us */ + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX; + + if (!((rx_stats_rcvd->mpdu_end.overflow_err) || + (rx_stats_rcvd->attention.fcs_err) || + (rx_stats_rcvd->attention.mpdu_length_err) || + (rx_stats_rcvd->attention.msdu_length_err) || + (rx_stats_rcvd->attention.tkip_mic_err) || + (rx_stats_rcvd->attention.decrypt_err))) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER; + + if (rx_stats_rcvd->mpdu_start.encrypted) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED; + + if (rx_stats_rcvd->attention.first_mpdu) { + MCS *mcs = &info->aggr_stats.RxMCS; + u32 ht_vht_sig; + + /* Flush the cached stats as this is the first MPDU. */ + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) { + if (rx_stats_rcvd->ppdu_start.l_sig_rate_select) { + mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_CCK; + mcs->mcs_s.rate = cck_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate); + } else { + mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_OFDM; + mcs->mcs_s.rate = ofdm_ratecode_mapping(rx_stats_rcvd->ppdu_start.l_sig_rate); + } + /*BW is 0 for legacy cases*/ + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_1) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3); + //mcs->mcs_s.nss = (ht_vht_sig & BITMASK(7)) >> 3; + mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_HT; + mcs->mcs_s.rate = ((ht_vht_sig & BITMASK(7)) % 8) & 0xF; + mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1); + mcs->mcs_s.short_gi = + ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1); + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_2) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3); + mcs->mcs_s.preamble = WIFI_HW_RATECODE_PREAM_VHT; + mcs->mcs_s.rate = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4); + mcs->mcs_s.bw = (ht_vht_sig & 3); + mcs->mcs_s.short_gi = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1); + } + + info->aggr_stats.last_transmit_rate + = get_rate_v1(info->aggr_stats.RxMCS.mcs); + + info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb; + info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid; + } + rb_pkt_stats->link_layer_transmit_sequence + = rx_stats_rcvd->mpdu_start.seq_num; + + memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0], + RX_HTT_HDR_STATUS_LEN_V1); + + if ((rx_stats_rcvd->attention.last_mpdu + && rx_stats_rcvd->msdu_end.last_msdu) + || (rx_stats_rcvd->attention.first_mpdu + && rx_stats_rcvd->attention.last_mpdu)) { + info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.wb_timestamp_lower_32; + + status = populate_rx_aggr_stats(info); + } + + return status; +} + +static wifi_error parse_rx_stats(hal_info *info, u8 *buf, u16 size) +{ + wifi_error status = WIFI_SUCCESS; + rb_pkt_stats_t *rx_stats_rcvd = (rb_pkt_stats_t *)buf; + wifi_ring_buffer_entry *pRingBufferEntry; + u32 len_ring_buffer_entry = 0; + + if (size < sizeof(rb_pkt_stats_t)) { + ALOGE("%s Unexpected rx stats event length: %d", __FUNCTION__, size); + memset(info->rx_aggr_pkts, 0, info->rx_buf_size_occupied); + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + info->rx_buf_size_occupied = 0; + return WIFI_ERROR_UNKNOWN; + } + + len_ring_buffer_entry = sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry) + + RX_HTT_HDR_STATUS_LEN; + + if (len_ring_buffer_entry + info->rx_buf_size_occupied + > info->rx_buf_size_allocated) { + wifi_ring_buffer_entry *temp; + temp = (wifi_ring_buffer_entry *)realloc(info->rx_aggr_pkts, + len_ring_buffer_entry + info->rx_buf_size_occupied); + if (temp == NULL) { + ALOGE("%s: Failed to reallocate memory", __FUNCTION__); + free(info->rx_aggr_pkts); + info->rx_aggr_pkts = NULL; + return WIFI_ERROR_OUT_OF_MEMORY; + } + info->rx_aggr_pkts = temp; + memset((u8 *)info->rx_aggr_pkts + info->rx_buf_size_allocated, 0, + len_ring_buffer_entry + info->rx_buf_size_occupied + - info->rx_buf_size_allocated); + info->rx_buf_size_allocated = + len_ring_buffer_entry + info->rx_buf_size_occupied; + } + + pRingBufferEntry = (wifi_ring_buffer_entry *)((u8 *)info->rx_aggr_pkts + + info->rx_buf_size_occupied); + + info->rx_buf_size_occupied += len_ring_buffer_entry; + + /* Fill size of the entry in rb entry which can be used while populating + * the data. Actual size that needs to be sent to ring buffer is only pps + * entry size + */ + pRingBufferEntry->entry_size = len_ring_buffer_entry; + wifi_ring_per_packet_status_entry *rb_pkt_stats = + (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry)); + + /* Peer tx packet and it is an Rx packet for us */ + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_DIRECTION_TX; + + if (!((rx_stats_rcvd->mpdu_end.overflow_err) || + (rx_stats_rcvd->attention.fcs_err) || + (rx_stats_rcvd->attention.mpdu_length_err) || + (rx_stats_rcvd->attention.msdu_length_err) || + (rx_stats_rcvd->attention.tkip_mic_err) || + (rx_stats_rcvd->attention.decrypt_err))) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER; + + if (rx_stats_rcvd->mpdu_start.encrypted) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED; + + if (rx_stats_rcvd->attention.first_mpdu) { + MCS *mcs = &info->aggr_stats.RxMCS; + u32 ht_vht_sig; + + /* Flush the cached stats as this is the first MPDU. */ + memset(&info->aggr_stats, 0, sizeof(rx_aggr_stats)); + if (rx_stats_rcvd->ppdu_start.preamble_type == PREAMBLE_L_SIG_RATE) { + if (rx_stats_rcvd->ppdu_start.l_sig_rate_select) + mcs->mcs_s.preamble = WL_PREAMBLE_OFDM; + mcs->mcs_s.rate = rx_stats_rcvd->ppdu_start.l_sig_rate - 8; + /*BW is 0 for legacy cases*/ + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_1) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 3) & 0x3); + mcs->mcs_s.preamble = WL_PREAMBLE_HT; + mcs->mcs_s.rate = (ht_vht_sig & BITMASK(7)) >> 3; + mcs->mcs_s.bw = ((ht_vht_sig >> 7) & 1); + mcs->mcs_s.short_gi = + ((rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 7) & 1); + } else if (rx_stats_rcvd->ppdu_start.preamble_type == + PREAMBLE_VHT_SIG_A_2) { + ht_vht_sig = rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_1; + mcs->mcs_s.nss = ((ht_vht_sig >> 10) & 0x3); + mcs->mcs_s.preamble = WL_PREAMBLE_VHT; + mcs->mcs_s.rate = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 >> 4) & BITMASK(4); + mcs->mcs_s.bw = (ht_vht_sig & 3); + mcs->mcs_s.short_gi = + (rx_stats_rcvd->ppdu_start.ht_sig_vht_sig_a_2 & 1); + } + + info->aggr_stats.last_transmit_rate + = get_rate(info->aggr_stats.RxMCS.mcs); + + info->aggr_stats.rssi = rx_stats_rcvd->ppdu_start.rssi_comb; + info->aggr_stats.tid = rx_stats_rcvd->mpdu_start.tid; + } + rb_pkt_stats->link_layer_transmit_sequence + = rx_stats_rcvd->mpdu_start.seq_num; + + memcpy(&rb_pkt_stats->data[0], &rx_stats_rcvd->rx_hdr_status[0], + RX_HTT_HDR_STATUS_LEN); + + if ((rx_stats_rcvd->attention.last_mpdu + && rx_stats_rcvd->msdu_end.last_msdu) + || (rx_stats_rcvd->attention.first_mpdu + && rx_stats_rcvd->attention.last_mpdu)) { + info->aggr_stats.timestamp = rx_stats_rcvd->ppdu_end.tsf_timestamp; + status = populate_rx_aggr_stats(info); + } + + return status; +} + +static u16 get_tx_mcs_v1(u8 *data) +{ + MCS mcs; + RATE_CODE rate_code; + u16 extended_flags; + mcs.mcs = 0; + + rate_code = *((RATE_CODE*)(data + RATE_CODE_OFFSET)); + extended_flags = *((u16*)(data + EXT_FLAGS_OFFSET)); + + mcs.mcs_s.rate = rate_code.rateCode & 0xF; + mcs.mcs_s.nss = (rate_code.rateCode >> 4) & 0x3; + mcs.mcs_s.preamble = (rate_code.rateCode >> 6) & 0x3; + mcs.mcs_s.short_gi = (((extended_flags >> 12) & 0x1) == 1) ? 1 : 0; + mcs.mcs_s.bw = (rate_code.flags >> 5) & 0x3; + + return mcs.mcs; +} + +static u16 get_tx_mcs(u8 series, + struct tx_ppdu_start *ppdu_start) +{ + MCS mcs; + struct series_bw *sbw = NULL; + + mcs.mcs = 0; + + if (series == 0) { + if (ppdu_start->valid_s0_bw20) + sbw = &ppdu_start->s0_bw20; + else if (ppdu_start->valid_s0_bw40) + sbw = &ppdu_start->s0_bw40; + else if (ppdu_start->valid_s0_bw80) + sbw = &ppdu_start->s0_bw80; + else if (ppdu_start->valid_s0_bw160) + sbw = &ppdu_start->s0_bw160; + } else { + if (ppdu_start->valid_s1_bw20) + sbw = &ppdu_start->s1_bw20; + else if (ppdu_start->valid_s1_bw40) + sbw = &ppdu_start->s1_bw40; + else if (ppdu_start->valid_s1_bw80) + sbw = &ppdu_start->s1_bw80; + else if (ppdu_start->valid_s1_bw160) + sbw = &ppdu_start->s1_bw160; + } + + if (sbw) { + mcs.mcs_s.rate = sbw->rate; + mcs.mcs_s.nss = sbw->nss; + mcs.mcs_s.preamble = sbw->preamble_type; + mcs.mcs_s.short_gi = sbw->short_gi; + } + + return mcs.mcs; +} + +static void get_tx_aggr_stats(struct tx_ppdu_start *ppdu_start, hal_info *info) +{ + u32 baBitmap0 = 0; + u32 baBitmap1 = 0; + + info->pkt_stats->tx_seqnum_bitmap_31_0 = ppdu_start->seqnum_bitmap_31_0; + info->pkt_stats->tx_seqnum_bitmap_63_32 = ppdu_start->seqnum_bitmap_63_32; + + if (info->pkt_stats->isBlockAck) { + int baShift = ppdu_start->start_seq_num - info->pkt_stats->ba_seq_num; + //There are 4 scenarios in total: + //1.TxSeq No. >= BaSeq No. and no roll over. + //2.TxSeq No. >= BaSeq No. and TxSeq No. rolls over. + //3.TxSeq No. <= BaSeq No. and no roll over. + //4.TxSeq No. <= BaSeq No. and BaSeq No. rolls over. + + baBitmap0 = info->pkt_stats->ba_bitmap_31_0; + baBitmap1 = info->pkt_stats->ba_bitmap_63_32; + + if (((baShift >= 0) && (baShift < SEQ_NUM_RANGE/2)) || + (baShift < -SEQ_NUM_RANGE/2)) { + //Scenario No.1 and No.2 + baShift = baShift < -SEQ_NUM_RANGE/2 ? (SEQ_NUM_RANGE + baShift) : + baShift; + + if (baShift < BITMAP_VAR_SIZE) { + info->pkt_stats->shifted_bitmap_31_0 = + ((baBitmap1 << (32 - baShift)) | (baBitmap0 >> baShift)); + info->pkt_stats->shifted_bitmap_63_32 = baBitmap1 >> baShift; + } else { + info->pkt_stats->shifted_bitmap_31_0 = + baBitmap1 >> (baShift - BITMAP_VAR_SIZE); + info->pkt_stats->shifted_bitmap_63_32 = 0; + } + } else { + baShift = (baShift >= SEQ_NUM_RANGE/2) ? (SEQ_NUM_RANGE - baShift) : + -baShift; + if (baShift < BITMAP_VAR_SIZE) { + info->pkt_stats->shifted_bitmap_31_0 = baBitmap0 << baShift; + info->pkt_stats->shifted_bitmap_63_32 = + ((baBitmap0 << (32 - baShift)) | + (baBitmap1 >> baShift)); + } else { + info->pkt_stats->shifted_bitmap_31_0 = 0; + info->pkt_stats->shifted_bitmap_63_32 = + baBitmap0 << (baShift - BITMAP_VAR_SIZE); + } + } + } else { + info->pkt_stats->shifted_bitmap_31_0 = 0; + info->pkt_stats->shifted_bitmap_63_32 = 0; + } +} + +static void get_try_status_params(hal_info *info, + struct tx_ppdu_end *tx_ppdu_end) +{ + int try_list_index; + + if (tx_ppdu_end->stat.total_tries > 0) + try_list_index = tx_ppdu_end->stat.total_tries - 1; + else + try_list_index = 0; + + info->pkt_stats->tx_bandwidth = + tx_ppdu_end->try_list.try_st[try_list_index].packet_bw; + info->pkt_stats->series = + tx_ppdu_end->try_list.try_st[try_list_index].series; +} + +static wifi_error parse_tx_stats(hal_info *info, void *buf, + u32 buflen, u8 logtype) +{ + wifi_error status = WIFI_SUCCESS; + int i; + wifi_ring_buffer_entry *pRingBufferEntry = + (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats; + + wifi_ring_per_packet_status_entry *rb_pkt_stats = + (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + ALOGV("Received Tx stats: log_type : %d", logtype); + switch (logtype) + { + case PKTLOG_TYPE_TX_CTRL: + { + if (buflen < sizeof (wh_pktlog_txctl)) { + ALOGE("Unexpected tx_ctrl event length: %d", buflen); + return WIFI_ERROR_UNKNOWN; + } + + wh_pktlog_txctl *stats = (wh_pktlog_txctl *)buf; + struct tx_ppdu_start *ppdu_start = + (struct tx_ppdu_start *)(&stats->u.ppdu_start); + + if (ppdu_start->frame_control & BIT(DATA_PROTECTED)) + rb_pkt_stats->flags |= + PER_PACKET_ENTRY_FLAGS_PROTECTED; + rb_pkt_stats->link_layer_transmit_sequence + = ppdu_start->start_seq_num; + info->pkt_stats->start_seq_num = ppdu_start->start_seq_num; + rb_pkt_stats->tid = ppdu_start->qos_ctl & 0xF; + rb_pkt_stats->MCS = get_tx_mcs(info->pkt_stats->series, ppdu_start) | + (info->pkt_stats->tx_bandwidth << BW_OFFSET); + rb_pkt_stats->last_transmit_rate = get_rate(rb_pkt_stats->MCS); + + if (ppdu_start->ampdu) + get_tx_aggr_stats(ppdu_start, info); + info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL); + } + break; + case PKTLOG_TYPE_TX_STAT: + { + if (buflen < sizeof(struct tx_ppdu_end)) { + ALOGE("Unexpected tx_stat event length: %d", buflen); + return WIFI_ERROR_UNKNOWN; + } + + /* This should be the first event for tx-stats: So, + * previous stats are invalid. Flush the old stats and treat + * this as new packet + */ + if (info->pkt_stats->tx_stats_events) + memset(rb_pkt_stats, 0, + sizeof(wifi_ring_per_packet_status_entry)); + + struct tx_ppdu_end *tx_ppdu_end = (struct tx_ppdu_end*)(buf); + + info->pkt_stats->ba_seq_num = tx_ppdu_end->stat.ba_start_seq_num; + info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status; + + if (tx_ppdu_end->stat.tx_ok) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + info->pkt_stats->isBlockAck = tx_ppdu_end->stat.ba_status; + + info->pkt_stats->ba_bitmap_31_0 = tx_ppdu_end->stat.ba_bitmap_31_0; + info->pkt_stats->ba_bitmap_63_32 = + tx_ppdu_end->stat.ba_bitmap_63_32; + rb_pkt_stats->transmit_success_timestamp = + tx_ppdu_end->try_list.try_st[0].timestamp; + rb_pkt_stats->rssi = tx_ppdu_end->stat.ack_rssi_ave; + rb_pkt_stats->num_retries = tx_ppdu_end->stat.total_tries; + get_try_status_params(info, tx_ppdu_end); + + info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT); + } + break; + case PKTLOG_TYPE_TX_MSDU_ID: + { + memset(info->pkt_stats, 0, sizeof(struct pkt_stats_s)); + info->pkt_stats->num_msdu = *(u8 *)buf; + info->pkt_stats->tx_stats_events = BIT(PKTLOG_TYPE_TX_MSDU_ID); + } + break; + case PKTLOG_TYPE_RC_UPDATE: + case PKTLOG_TYPE_TX_FRM_HDR: + case PKTLOG_TYPE_RC_FIND: + case PKTLOG_TYPE_TX_VIRT_ADDR: + ALOGV("%s : Unsupported log_type received : %d", + __FUNCTION__, logtype); + break; + default: + { + ALOGV("%s : Unexpected log_type received : %d", + __FUNCTION__, logtype); + return WIFI_ERROR_UNKNOWN; + } + } + + if ((info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_CTRL)) && + (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) && + (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_MSDU_ID))) { + /* No tx payload as of now, add the length to parameter size(3rd) + * if there is any payload + */ + + if (info->pkt_stats->num_msdu == 1) { + if (!(rb_pkt_stats->flags & PER_PACKET_ENTRY_FLAGS_TX_SUCCESS)) + rb_pkt_stats->rssi = INVALID_RSSI; + /* Handle non aggregated cases */ + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, + sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer : %d", logtype); + } + } else { + /* Handle aggregated cases */ + for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) { + if (i < BITMAP_VAR_SIZE) { + if (info->pkt_stats->tx_seqnum_bitmap_31_0 & BIT(i)) { + if (info->pkt_stats->shifted_bitmap_31_0 & BIT(i)) { + rb_pkt_stats->flags |= + PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } else { + rb_pkt_stats->flags &= + ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->rssi = INVALID_RSSI; + } + } else { + continue; + } + } else { + if (info->pkt_stats->tx_seqnum_bitmap_63_32 + & BIT(i - BITMAP_VAR_SIZE)) { + if (info->pkt_stats->shifted_bitmap_63_32 + & BIT(i - BITMAP_VAR_SIZE)) { + rb_pkt_stats->flags |= + PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } else { + rb_pkt_stats->flags &= + ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->rssi = INVALID_RSSI; + } + } else { + continue; + } + } + rb_pkt_stats->link_layer_transmit_sequence = + info->pkt_stats->start_seq_num + i; + + /* Take care of roll over SEQ_NUM_RANGE */ + rb_pkt_stats->link_layer_transmit_sequence &= 0xFFF; + + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, + sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer: %d", logtype); + break; + } + } + } + + /* Flush the local copy after writing the stats to ring buffer + * for tx-stats. + */ + info->pkt_stats->tx_stats_events = 0; + memset(rb_pkt_stats, 0, + sizeof(wifi_ring_per_packet_status_entry)); + + } + + return status; +} + +wifi_error write_per_packet_stats_to_rb(hal_info *info, u8 *buf, u16 length) +{ + wifi_ring_buffer_entry rb_entry_hdr; + struct timeval time; + wifi_error status; + + rb_entry_hdr.entry_size = length; + rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + rb_entry_hdr.type = ENTRY_TYPE_PKT; + gettimeofday(&time, NULL); + rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + /* Write if verbose and handler is set */ + if (info->rb_infos[PKT_STATS_RB_ID].verbose_level >= 3 && + info->on_ring_buffer_data) { + /* Write header and payload separately to avoid + * complete payload memcpy */ + status = ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID], + (u8*)&rb_entry_hdr, + sizeof(wifi_ring_buffer_entry), + 0, + sizeof(wifi_ring_buffer_entry) + length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write driver prints rb header %d", status); + return status; + } + status = ring_buffer_write(&info->rb_infos[PKT_STATS_RB_ID], + buf, + length, + 1, + length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write PKT stats into the ring buffer"); + } + } + + return WIFI_SUCCESS; +} + +static wifi_error parse_tx_pkt_fate_stats(hal_info *info, u8 *buf, u16 size) +{ + pktdump_hdr *log = (pktdump_hdr *)buf; + wifi_tx_report_i *pkt_fate_stats; + + if (info->pkt_fate_stats->n_tx_stats_collected >= MAX_FATE_LOG_LEN) { + ALOGD("Only %u events are expected, don't process this event", + MAX_FATE_LOG_LEN); + return WIFI_SUCCESS; + } + + pkt_fate_stats = &info->pkt_fate_stats->tx_fate_stats[ + info->pkt_fate_stats->n_tx_stats_collected]; + + pkt_fate_stats->fate = (wifi_tx_packet_fate)log->status; + if (log->type == TX_MGMT_PKT) + pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_80211_MGMT; + else + pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_ETHERNET_II; + + pkt_fate_stats->frame_inf.driver_timestamp_usec = log->driver_ts; + pkt_fate_stats->frame_inf.firmware_timestamp_usec = log->fw_ts; + pkt_fate_stats->frame_inf.frame_len = size - sizeof(pktdump_hdr); + pkt_fate_stats->frame_inf.frame_content = + (char *)malloc(pkt_fate_stats->frame_inf.frame_len * sizeof(char)); + if (pkt_fate_stats->frame_inf.frame_content) { + memcpy(pkt_fate_stats->frame_inf.frame_content, + buf + sizeof(pktdump_hdr), pkt_fate_stats->frame_inf.frame_len); + } else { + ALOGE("Failed to allocate mem for Tx frame_content for packet: %zu", + info->pkt_fate_stats->n_tx_stats_collected); + pkt_fate_stats->frame_inf.frame_len = 0; + } + + info->pkt_fate_stats->n_tx_stats_collected++; + + return WIFI_SUCCESS; +} + + +static wifi_error parse_rx_pkt_fate_stats(hal_info *info, u8 *buf, u16 size) +{ + pktdump_hdr *log = (pktdump_hdr *)buf; + wifi_rx_report_i *pkt_fate_stats; + + if (info->pkt_fate_stats->n_rx_stats_collected >= MAX_FATE_LOG_LEN) { + ALOGD("Only %u events are expected, don't process this event", + MAX_FATE_LOG_LEN); + return WIFI_SUCCESS; + } + + pkt_fate_stats = &info->pkt_fate_stats->rx_fate_stats[ + info->pkt_fate_stats->n_rx_stats_collected]; + + pkt_fate_stats->fate = (wifi_rx_packet_fate)log->status; + if (log->type == RX_MGMT_PKT) + pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_80211_MGMT; + else + pkt_fate_stats->frame_inf.payload_type = FRAME_TYPE_ETHERNET_II; + + pkt_fate_stats->frame_inf.driver_timestamp_usec = log->driver_ts; + pkt_fate_stats->frame_inf.firmware_timestamp_usec = log->fw_ts; + pkt_fate_stats->frame_inf.frame_len = size - sizeof(pktdump_hdr); + pkt_fate_stats->frame_inf.frame_content = + (char *)malloc(pkt_fate_stats->frame_inf.frame_len * sizeof(char)); + if (pkt_fate_stats->frame_inf.frame_content) { + memcpy(pkt_fate_stats->frame_inf.frame_content, + buf + sizeof(pktdump_hdr), pkt_fate_stats->frame_inf.frame_len); + } else { + ALOGE("Failed to allocate mem for Rx frame_content for packet: %zu", + info->pkt_fate_stats->n_rx_stats_collected); + pkt_fate_stats->frame_inf.frame_len = 0; + } + + info->pkt_fate_stats->n_rx_stats_collected++; + + return WIFI_SUCCESS; +} + + +static wifi_error trigger_fate_stats(hal_info *info, u8 *buf, u16 size) +{ + int i; + packet_fate_monitor_info *pkt_fate_stats = info->pkt_fate_stats; + + for (i=0; i<MAX_FATE_LOG_LEN; i++) { + if (pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content) { + free (pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content); + pkt_fate_stats->tx_fate_stats[i].frame_inf.frame_content = NULL; + } + + if (pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content) { + free (pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content); + pkt_fate_stats->rx_fate_stats[i].frame_inf.frame_content = NULL; + } + } + memset(pkt_fate_stats, 0, sizeof(packet_fate_monitor_info)); + + return WIFI_SUCCESS; +} + + +static wifi_error report_fate_stats(hal_info *info, u8 *buf, u16 size) +{ + ALOGI("Fate Tx-Rx: Packet fate stats stop received"); + return WIFI_SUCCESS; +} + + +static wifi_error parse_pkt_fate_stats(hal_info *info, u8 *buf, u16 size) +{ + pktdump_hdr *hdr = (pktdump_hdr *)buf; + + switch (hdr->type) + { + case START_MONITOR: + trigger_fate_stats(info, buf, size); + break; + case STOP_MONITOR: + report_fate_stats(info, buf, size); + break; + case TX_MGMT_PKT: + case TX_DATA_PKT: + parse_tx_pkt_fate_stats(info, buf, size); + break; + case RX_MGMT_PKT: + case RX_DATA_PKT: + parse_rx_pkt_fate_stats(info, buf, size); + break; + default: + ALOGE("Unsupported type : %d", hdr->type); + return WIFI_ERROR_INVALID_ARGS; + } + return WIFI_SUCCESS; +} + +/* + * --------------------------------------------------------------------------------- + * | pkt log | packet log data contain sub packet log info | + * | header |------------------------------------------------------------------| + * | | sub pkt log | sub pkt log | sub pkt log | sub pkt log | | + * | | header | data | header | data |..... | + * |-------------------------------------------------------------------------------- + */ +static wifi_error parse_stats_sw_event(hal_info *info, + wh_pktlog_hdr_v2_t *pkt_stats_header) +{ + u32 pkt_stats_len; + int num_of_node = 0; + u8 *data; + u8 *node_pkt_data; + wh_pktlog_hdr_v2_t *pkt_stats_node_header; + int node_pkt_type,pkt_sub_type,i; + int node_pkt_len = 0; + wifi_error status = WIFI_SUCCESS; + node_pkt_stats node_pkt_t; + node_pkt_t.bmap_enqueued = 0; + node_pkt_t.bmap_failed = 0; + wifi_ring_buffer_entry *pRingBufferEntry = + (wifi_ring_buffer_entry *)info->pkt_stats->tx_stats; + + wifi_ring_per_packet_status_entry *rb_pkt_stats = + (wifi_ring_per_packet_status_entry *)(pRingBufferEntry + 1); + + pkt_stats_len = pkt_stats_header->size; + data = ((u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t)); + num_of_node = (pkt_stats_header->reserved >> 16) & 0xFFFF; + pkt_sub_type = pkt_stats_header->reserved & 0xFFFF; + + do { + if (pkt_stats_len < sizeof(wh_pktlog_hdr_v2_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + if (pkt_sub_type == 1) { + pkt_stats_node_header = (wh_pktlog_hdr_v2_t *)data; + if (pkt_stats_node_header) { + node_pkt_type = pkt_stats_node_header->log_type; + node_pkt_len = pkt_stats_node_header->size; + node_pkt_data = ((u8 *)pkt_stats_node_header + sizeof(wh_pktlog_hdr_v2_t)); + switch (node_pkt_type) { + case PKTLOG_TYPE_TX_CTRL: + info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_CTRL); + break; + case PKTLOG_TYPE_TX_STAT: + { + memset(rb_pkt_stats, 0, sizeof(wifi_ring_per_packet_status_entry)); + memset(&node_pkt_t, 0, sizeof(node_pkt_stats)); + node_pkt_t.frm_ctrl = *((u16*)(node_pkt_data + FRAME_CTRL_OFFSET)); + if (node_pkt_t.frm_ctrl & BIT(DATA_PROTECTED)) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_PROTECTED; + rb_pkt_stats->transmit_success_timestamp = + *((u64*)(node_pkt_data + TX_SUCCESS_TMS_OFFSET)); + rb_pkt_stats->link_layer_transmit_sequence = + *((u16*)(node_pkt_data + LINK_LAYER_TX_SQN_OFFSET)); + node_pkt_t.tx_ok = *((u8*)(node_pkt_data + TX_STATUS_OFFSET)); + if (node_pkt_t.tx_ok == 0) + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + rb_pkt_stats->rssi = *((u8*)(node_pkt_data + TX_RSSI_OFFSET)); + rb_pkt_stats->num_retries = *((u8*)(node_pkt_data + NO_RETRIES_OFFSET)); + node_pkt_t.qos_ctrl = *((u8*)(node_pkt_data + QOS_CTRL_OFFSET)); + rb_pkt_stats->tid = node_pkt_t.qos_ctrl & 0xF; + rb_pkt_stats->MCS = get_tx_mcs_v1(node_pkt_data); + if ((rb_pkt_stats->MCS & INVALID_RATE_CODE) != INVALID_RATE_CODE) + rb_pkt_stats->last_transmit_rate = get_rate_v1(rb_pkt_stats->MCS); + node_pkt_t.bmap_failed = *((u64*)(node_pkt_data + BMAP_FAILED_OFFSET)); + node_pkt_t.bmap_enqueued = *((u64*)(node_pkt_data + BMAP_ENQUEUED_OFFSET)); + + info->pkt_stats->tx_stats_events |= BIT(PKTLOG_TYPE_TX_STAT); + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_80211_HEADER; + } + break; + default: + // TODO: Unexpected PKTLOG types + break; + } + if (info->pkt_stats->tx_stats_events & BIT(PKTLOG_TYPE_TX_STAT)) { + /* if bmap_enqueued is 1 ,Handle non aggregated cases */ + if (node_pkt_t.bmap_enqueued == 1) { + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, + sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer : %d", node_pkt_type); + } + } else { + /* if bmap_enqueued is more than 1 ,Handle aggregated cases */ + for (i = 0; i < MAX_BA_WINDOW_SIZE; i++) { + if (((node_pkt_t.bmap_enqueued >> i) & 0x1) == 1) { + if (((node_pkt_t.bmap_failed >> i) & 0x1) == 1) { + rb_pkt_stats->flags &= ~PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } else { + rb_pkt_stats->flags |= PER_PACKET_ENTRY_FLAGS_TX_SUCCESS; + } + status = update_stats_to_ring_buf(info, + (u8 *)pRingBufferEntry, + sizeof(wifi_ring_buffer_entry) + + sizeof(wifi_ring_per_packet_status_entry)); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write into the ring buffer : %d", node_pkt_type); + break; + } + rb_pkt_stats->link_layer_transmit_sequence += 1; + } + } + } + } + } + pkt_stats_len = (pkt_stats_len - (sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len)); + data = (u8*) (data + sizeof(wh_pktlog_hdr_v2_t) + node_pkt_len); + info->pkt_stats->tx_stats_events = 0; + } else { + //TODO parsing of unknown packet sub type + status = WIFI_ERROR_INVALID_ARGS; + break; + } + } while (!info->clean_up && (pkt_stats_len > 0)); + return status; +} + +/* Added This function to parse stats based on PKT_LOG_V2 Version */ +static wifi_error parse_stats_record_v2(hal_info *info, + wh_pktlog_hdr_v2_t *pkt_stats_header) +{ + wifi_error status = WIFI_SUCCESS; + + if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) { + /* Ignore the event if it doesn't carry RX descriptor */ + if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK) + status = parse_rx_stats_v2(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size); + else + status = WIFI_SUCCESS; + } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP_V2) { + pthread_mutex_lock(&info->pkt_fate_stats_lock); + if (info->fate_monitoring_enabled) { + if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2) + status = parse_pkt_fate_stats(info, + (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t), + pkt_stats_header->size); + else + status = WIFI_SUCCESS; + } else + status = WIFI_SUCCESS; + pthread_mutex_unlock(&info->pkt_fate_stats_lock); + } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_SW_EVENT) { + status = parse_stats_sw_event(info, pkt_stats_header); + } else if (pkt_stats_header->log_type == PKTLOG_TYPE_TX_STAT || + pkt_stats_header->log_type == PKTLOG_TYPE_RX_STATBUF || + pkt_stats_header->log_type == PKTLOG_TYPE_LITE_T2H || + pkt_stats_header->log_type == PKTLOG_TYPE_LITE_RX) { + //TODO Parsing of per packet log. + } else { + //No Parsing on Default packet log type. + } + return status; +} + +static wifi_error parse_stats_record_v1(hal_info *info, + wh_pktlog_hdr_t *pkt_stats_header) +{ + wifi_error status; + if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_STATS) { + status = write_per_packet_stats_to_rb(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size); + } else if (pkt_stats_header->log_type == PKTLOG_TYPE_RX_STAT) { + /* Ignore the event if it doesn't carry RX descriptor */ + if (pkt_stats_header->flags & PKT_INFO_FLG_RX_RXDESC_MASK) + status = parse_rx_stats(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size); + else + status = WIFI_SUCCESS; + } else if (pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP || + pkt_stats_header->log_type == PKTLOG_TYPE_PKT_DUMP_V2) { + pthread_mutex_lock(&info->pkt_fate_stats_lock); + if (info->fate_monitoring_enabled) { + if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2) + status = parse_pkt_fate_stats(info, + (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_v2_t), + pkt_stats_header->size); + else + status = parse_pkt_fate_stats(info, + (u8 *)pkt_stats_header + sizeof(wh_pktlog_hdr_t), + pkt_stats_header->size); + } else + status = WIFI_SUCCESS; + pthread_mutex_unlock(&info->pkt_fate_stats_lock); + } else { + status = parse_tx_stats(info, + (u8 *)(pkt_stats_header + 1), + pkt_stats_header->size, + pkt_stats_header->log_type); + } + return status; +} + +static wifi_error parse_stats(hal_info *info, u8 *data, u32 buflen) +{ + wh_pktlog_hdr_t *pkt_stats_header; + wh_pktlog_hdr_v2_t *pkt_stats_header_v2_t; + wifi_error status = WIFI_SUCCESS; + + do { + u32 record_len; + + if (buflen < sizeof(wh_pktlog_hdr_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + + pkt_stats_header = (wh_pktlog_hdr_t *)data; + pkt_stats_header_v2_t = (wh_pktlog_hdr_v2_t *)data; + + if (info->pkt_log_ver == PKT_LOG_V2) { + if (buflen < sizeof(wh_pktlog_hdr_v2_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size); + } else { + if (pkt_stats_header->flags & PKT_INFO_FLG_PKT_DUMP_V2){ + if (buflen < sizeof(wh_pktlog_hdr_v2_t)) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + record_len = (sizeof(wh_pktlog_hdr_v2_t) + pkt_stats_header_v2_t->size); + } else { + record_len = (sizeof(wh_pktlog_hdr_t) + pkt_stats_header->size); + } + } + + if (buflen < record_len) { + status = WIFI_ERROR_INVALID_ARGS; + break; + } + /* Pkt_log_V2 based packet parsing */ + if (info->pkt_log_ver == PKT_LOG_V2) { + status = parse_stats_record_v2(info, pkt_stats_header_v2_t); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to parse the stats type : %d", + pkt_stats_header_v2_t->log_type); + return status; + } + /* Pkt_log_V1 based packet parsing */ + } else { + status = parse_stats_record_v1(info, pkt_stats_header); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to parse the stats type : %d", + pkt_stats_header->log_type); + return status; + } + } + data += record_len; + buflen -= record_len; + + } while (!info->clean_up && (buflen > 0)); + + return status; +} + +wifi_error process_driver_prints(hal_info *info, u8 *buf, u16 length) +{ + wifi_ring_buffer_entry rb_entry_hdr; + struct timeval time; + wifi_error status; + + rb_entry_hdr.entry_size = length; + rb_entry_hdr.flags = RING_BUFFER_ENTRY_FLAGS_HAS_TIMESTAMP; + rb_entry_hdr.type = ENTRY_TYPE_DATA; + gettimeofday(&time, NULL); + rb_entry_hdr.timestamp = (u64)time.tv_usec + (u64)time.tv_sec * 1000 * 1000; + + /* Write if verbose and handler is set */ + if (info->rb_infos[DRIVER_PRINTS_RB_ID].verbose_level >= 1 && + info->on_ring_buffer_data) { + /* Write header and payload separately to avoid + * complete payload memcpy */ + status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID], + (u8*)&rb_entry_hdr, + sizeof(wifi_ring_buffer_entry), + 0, + sizeof(wifi_ring_buffer_entry) + length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write driver prints rb header %d", status); + return status; + } + status = ring_buffer_write(&info->rb_infos[DRIVER_PRINTS_RB_ID], + buf, length, 1, length); + if (status != WIFI_SUCCESS) { + ALOGE("Failed to write driver prints rb payload %d", status); + return status; + } + } + + return WIFI_SUCCESS; +} + +wifi_error diag_message_handler(hal_info *info, nl_msg *msg) +{ + tAniNlHdr *wnl; + u8 *buf; + wifi_error status; + tAniCLDHdr *clh = NULL; + int cmd = 0; + + if (info->cldctx) { + struct nlattr *attrs[CLD80211_ATTR_MAX + 1]; + struct genlmsghdr *genlh; + struct nlattr *tb_vendor[CLD80211_ATTR_MAX + 1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + + genlh = (struct genlmsghdr *)nlmsg_data(nlh); + if (genlh->cmd == ANI_NL_MSG_PUMAC || + genlh->cmd == ANI_NL_MSG_LOG || + genlh->cmd == ANI_NL_MSG_CNSS_DIAG || + genlh->cmd == WLAN_NL_MSG_OEM) + { + cmd = genlh->cmd; + int result = nla_parse(attrs, CLD80211_ATTR_MAX, genlmsg_attrdata(genlh, 0), + genlmsg_attrlen(genlh, 0), NULL); + + if (!result && attrs[CLD80211_ATTR_VENDOR_DATA]) { + nla_parse(tb_vendor, CLD80211_ATTR_MAX, + (struct nlattr *)nla_data(attrs[CLD80211_ATTR_VENDOR_DATA]), + nla_len(attrs[CLD80211_ATTR_VENDOR_DATA]), NULL); + + if (tb_vendor[CLD80211_ATTR_DATA]) { + clh = (tAniCLDHdr *)nla_data(tb_vendor[CLD80211_ATTR_DATA]); + } + } else { + ALOGE("Invalid data received"); + return WIFI_ERROR_UNKNOWN; + } + if (genlh->cmd != WLAN_NL_MSG_OEM && !clh) { + ALOGE("Invalid data received from driver"); + return WIFI_ERROR_UNKNOWN; + } + + if((info->wifihal_ctrl_sock.s > 0) && (genlh->cmd == WLAN_NL_MSG_OEM)) { + wifihal_ctrl_event_t *ctrl_evt; + wifihal_mon_sock_t *reg; + + if (!(tb_vendor[CLD80211_ATTR_DATA] || tb_vendor[CLD80211_ATTR_CMD])) { + ALOGE("Invalid oem data received from driver"); + return WIFI_ERROR_UNKNOWN; + } + ctrl_evt = (wifihal_ctrl_event_t *)malloc(sizeof(*ctrl_evt) + nlh->nlmsg_len); + + if(ctrl_evt == NULL) + { + ALOGE("Memory allocation failure"); + return WIFI_ERROR_OUT_OF_MEMORY; + } + memset((char *)ctrl_evt, 0, sizeof(*ctrl_evt) + nlh->nlmsg_len); + + ctrl_evt->family_name = CLD80211_FAMILY; + ctrl_evt->cmd_id = WLAN_NL_MSG_OEM; + ctrl_evt->data_len = nlh->nlmsg_len; + memcpy(ctrl_evt->data, (char *)nlh, ctrl_evt->data_len); + + //! Send oem data to all the registered clients + + list_for_each_entry(reg, &info->monitor_sockets, list) { + + if (reg->family_name != CLD80211_FAMILY || reg->cmd_id != WLAN_NL_MSG_OEM) + continue; + + /* found match! */ + /* Indicate the received OEM msg to respective client + it is responsibility of the registered client to check + the oem_msg is meant for them or not based on oem_msg sub type */ + ALOGI("send oem msg of len : %d to apps",ctrl_evt->data_len); + if (sendto(info->wifihal_ctrl_sock.s, (char *)ctrl_evt, + sizeof(*ctrl_evt) + ctrl_evt->data_len, 0, + (struct sockaddr *)®->monsock, reg->monsock_len) < 0) + { + int _errno = errno; + ALOGE("socket send failed : %d",_errno); + + if (_errno == ENOBUFS || _errno == EAGAIN) { + /* + * The socket send buffer could be full. This + * may happen if client programs are not + * receiving their pending messages. Close and + * reopen the socket as a workaround to avoid + * getting stuck being unable to send any new + * responses. + */ + } + } + } + free(ctrl_evt); + return WIFI_SUCCESS; + } + } + } else { + wnl = (tAniNlHdr *)nlmsg_hdr(msg); + cmd = wnl->nlh.nlmsg_type; + } + + /* Check nlmsg_type also to avoid processing unintended msgs */ + if (cmd == ANI_NL_MSG_PUMAC) { + if (!info->cldctx) { + if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) || + (wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + ntohs(wnl->clh.wmsg.length)))) { + ALOGE("Received UMAC message with insufficent length: %d", + wnl->nlh.nlmsg_len); + return WIFI_ERROR_UNKNOWN; + } + clh = &wnl->clh; + } + if (clh->wmsg.type == ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE) { + uint32_t diag_host_type; + + buf = (uint8_t *)(clh + 1); + diag_host_type = *(uint32_t *)(buf); +#ifdef QC_HAL_DEBUG + ALOGV("diag type = %d", diag_host_type); +#endif + buf += sizeof(uint32_t); //diag_type + if (diag_host_type == DIAG_TYPE_HOST_EVENTS) { + host_event_hdr_t *event_hdr = + (host_event_hdr_t *)(buf); +#ifdef QC_HAL_DEBUG + ALOGV("diag event_id = %x length %d", + event_hdr->event_id, event_hdr->length); +#endif + buf += sizeof(host_event_hdr_t); + switch (event_hdr->event_id) { + case EVENT_WLAN_WAKE_LOCK: + process_wakelock_event(info, buf, event_hdr->length); + break; + case EVENT_WLAN_PE: + process_wlan_pe_event(info, buf, event_hdr->length); + break; + case EVENT_WLAN_EAPOL: + process_wlan_eapol_event(info, buf, event_hdr->length); + break; + case EVENT_WLAN_LOG_COMPLETE: + process_wlan_log_complete_event(info, buf, event_hdr->length); + break; + case EVENT_WLAN_LOW_RESOURCE_FAILURE: + process_wlan_low_resource_failure(info, buf, event_hdr->length); + break; + case EVENT_WLAN_STA_DATA_STALL: + process_wlan_data_stall_event(info, buf, event_hdr->length); + break; + case EVENT_WLAN_POWERSAVE_WOW: + case EVENT_WLAN_POWERSAVE_WOW_STATS: + case EVENT_WLAN_STA_KICKOUT: + case EVENT_WLAN_BRINGUP_STATUS: + /* Handle DIAG events properly */ + break; + default: + return WIFI_SUCCESS; + } + } else if (diag_host_type == DIAG_TYPE_HOST_LOG_MSGS) { + drv_msg_t *drv_msg = (drv_msg_t *) (buf); +#ifdef QC_HAL_DEBUG + ALOGV("diag event_type = %0x length = %d", + drv_msg->event_type, drv_msg->length); +#endif + if (drv_msg->event_type == WLAN_PKT_LOG_STATS) { + if ((info->prev_seq_no + 1) != + drv_msg->u.pkt_stats_event.msg_seq_no) { + ALOGE("Few pkt stats messages missed: rcvd = %d, prev = %d", + drv_msg->u.pkt_stats_event.msg_seq_no, + info->prev_seq_no); + if (info->pkt_stats->tx_stats_events) { + info->pkt_stats->tx_stats_events = 0; + memset(&info->pkt_stats->tx_stats, 0, + sizeof(wifi_ring_per_packet_status_entry)); + } + } + + info->prev_seq_no = + drv_msg->u.pkt_stats_event.msg_seq_no; + status = parse_stats(info, + drv_msg->u.pkt_stats_event.payload, + drv_msg->u.pkt_stats_event.payload_len); + if (status != WIFI_SUCCESS) { + ALOGE("%s: Failed to parse Tx-Rx stats", __FUNCTION__); + ALOGE("Received msg Seq_num : %d", + drv_msg->u.pkt_stats_event.msg_seq_no); + hexdump((char *)drv_msg->u.pkt_stats_event.payload, + drv_msg->u.pkt_stats_event.payload_len); + return status; + } + } + } + } + } else if (cmd == ANI_NL_MSG_LOG) { + if (!info->cldctx) { + if ((wnl->nlh.nlmsg_len <= sizeof(tAniNlHdr)) || + (wnl->nlh.nlmsg_len < (sizeof(tAniNlHdr) + wnl->clh.wmsg.length))) { + ALOGE("Received LOG message with insufficent length: %d", + wnl->nlh.nlmsg_len); + return WIFI_ERROR_UNKNOWN; + } + clh = &wnl->clh; + } + if (clh->wmsg.type == ANI_NL_MSG_LOG_HOST_PRINT_TYPE) { + process_driver_prints(info, (u8 *)(clh + 1), clh->wmsg.length); + } else if (clh->wmsg.type == ANI_NL_MSG_LOG_FW_MSG_TYPE) { + process_firmware_prints(info, (u8 *)(clh + 1), clh->wmsg.length); + } + } else if (cmd == ANI_NL_MSG_CNSS_DIAG) { + uint16_t diag_fw_type; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + + if (!info->cldctx) { + buf = (uint8_t *)NLMSG_DATA(wnl) + sizeof(wnl->clh.radio); + } else { + buf = (uint8_t *)&clh->wmsg; + } + + fw_event_hdr_t *event_hdr = + (fw_event_hdr_t *)(buf); + if (!info->cldctx) { + if ((wnl->nlh.nlmsg_len <= NLMSG_HDRLEN + sizeof(fw_event_hdr_t)) || + (wnl->nlh.nlmsg_len < (NLMSG_HDRLEN + sizeof(fw_event_hdr_t) + + event_hdr->length))) { + ALOGE("Received CNSS_DIAG message with insufficent length: %d", + wnl->nlh.nlmsg_len); + return WIFI_ERROR_UNKNOWN; + } + } else { + if (nlh->nlmsg_len <= NLMSG_HDRLEN + sizeof(dbglog_slot)) { + ALOGE("Received CNSS_DIAG message with insufficent length: %d: %s:%d", + nlh->nlmsg_len, __FUNCTION__, __LINE__); + return WIFI_ERROR_UNKNOWN; + } + } + diag_fw_type = event_hdr->diag_type; + if (diag_fw_type == DIAG_TYPE_FW_MSG) { + dbglog_slot *slot; + u32 length = 0; + + slot = (dbglog_slot *)buf; + length = get_le32((u8 *)&slot->length); + if (nlh->nlmsg_len < (NLMSG_HDRLEN + sizeof(dbglog_slot) + + length)) { + ALOGE("Received CNSS_DIAG message with insufficent length: %d:" + " expected: %zu, %s:%d", + nlh->nlmsg_len, + (NLMSG_HDRLEN + sizeof(dbglog_slot) +length), + __FUNCTION__, + __LINE__); + return WIFI_ERROR_UNKNOWN; + } + process_fw_diag_msg(info, &slot->payload[0], length); + } + } + return WIFI_SUCCESS; +} diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger_diag.h b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.h new file mode 100644 index 0000000..fc23cb7 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifilogger_diag.h @@ -0,0 +1,250 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_WIFILOGGER_DIAG_H__ +#define __WIFI_HAL_WIFILOGGER_DIAG_H__ + +#include "common.h" +#include "wifi_hal.h" +#include "wifilogger_event_defs.h" + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <linux/rtnetlink.h> + +#define ANI_NL_MSG_BASE 0x10 /* Some arbitrary base */ +#define WIFI_HAL_USER_SOCK_PORT 646 +#define WLAN_NL_MSG_CNSS_HOST_EVENT_LOG 17 +#define ANI_NL_MSG_LOG_HOST_EVENT_LOG_TYPE 0x5050 +#define ANI_NL_MSG_LOG_HOST_PRINT_TYPE 89 +#define ANI_NL_MSG_LOG_FW_MSG_TYPE 92 + +#define WLAN_PKT_LOG_STATS 0x18E0 +#define FEATURE_NOT_SUPPORTED 0xFF + +#define DATA_STALL_OFFSET_REASON_CODE 256 +/* + * - verbose_level 0 corresponds to no collection + * - verbose_level 1 correspond to normal log level, with minimal user impact. + * this is the default value + * - verbose_level 2 are enabled when user is lazily trying to reproduce a + problem, wifi performances and power + * can be impacted but device should not otherwise be significantly impacted + * - verbose_level 3+ are used when trying to actively debug a problem + */ + +enum wifilogger_verbose_level { + VERBOSE_NO_COLLECTION, + VERBOSE_NORMAL_LOG, + VERBOSE_REPRO_PROBLEM, + VERBOSE_DEBUG_PROBLEM +}; + +enum wifilogger_fw_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_FW_MSG = 4, /* send fw message- to diag*/ +}; + +enum wifilogger_host_diag_type { + DIAG_TYPE_HOST_LOG_MSGS=1, + DIAG_TYPE_HOST_EVENTS=2, +}; + +enum wlan_diag_frame_type { + WLAN_DIAG_TYPE_CONFIG, + WLAN_DIAG_TYPE_EVENT, /* Diag Events */ + WLAN_DIAG_TYPE_LOG, /* Diag Logs */ + WLAN_DIAG_TYPE_MSG, /* F3 messages */ + WLAN_DIAG_TYPE_LEGACY_MSG, + WLAN_DIAG_TYPE_EVENT_V2, + WLAN_DIAG_TYPE_LOG_V2, + WLAN_DIAG_TYPE_MSG_V2, +}; + +typedef struct event_remap { + int q_event; + int g_event; +} event_remap_t; + +typedef struct { + u32 diag_type; + u32 timestamp; + u32 length; + u32 dropped; + /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */ + u_int8_t payload[0]; +}__attribute__((packed)) dbglog_slot; + +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, + ANI_NL_MSG_CNSS_DIAG = ANI_NL_MSG_BASE + 0x0B, + ANI_NL_MSG_LOG, + ANI_NL_MSG_MAX +} tAniNlModTypes; + +//All Netlink messages must contain this header +typedef struct sAniHdr { + unsigned short type; + unsigned short length; +} tAniHdr, tAniMsgHdr; + +typedef struct sAniCLDMsg { + int radio; // unit number of the radio + tAniHdr wmsg; // Airgo Message Header +} tAniCLDHdr; + +/* + * 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 + tAniCLDHdr clh; +} 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; + +typedef struct host_event_hdr_s +{ + u16 event_id; + u16 length; +} host_event_hdr_t; + +typedef struct fw_event_hdr_s +{ + u16 diag_type; + u16 length; +} fw_event_hdr_t; + +typedef struct +{ + u32 reserved:24; + u32 diag_event_type:8; +}__attribute__((packed)) fw_diag_msg_fixed_hdr_t; + +typedef struct +{ + u32 timestamp:24; + u32 diag_event_type:8; + /* Below 16-bit field has different formats based on event type */ + union { + u16 payload_len; + struct { + u8 payload_len; + u8 vdev_level:3; + u8 vdev_id:5; + }__attribute__((packed)) msg_hdr; + }__attribute__((packed)) u; + u16 diag_id; + u8 payload[0]; +}__attribute__((packed)) fw_diag_msg_hdr_t; + +typedef struct +{ + u32 unused:24; + u32 diag_event_type:8; + u32 timestamp; + /* Below 16-bit field has different formats based on event type */ + union { + u16 payload_len; + struct { + u8 payload_len; + u8 vdev_level:3; + u8 vdev_id:5; + }__attribute__((packed)) msg_hdr; + }__attribute__((packed)) u; + u16 diag_id; + u8 payload[0]; +}__attribute__((packed)) fw_diag_msg_hdr_v2_t; + +typedef struct wlan_wake_lock_event { + u32 status; + u32 reason; + u32 timeout; + u32 name_len; + char name[]; +} wlan_wake_lock_event_t; + +enum log_event_type { + WLAN_LOG_TYPE_NON_FATAL, + WLAN_LOG_TYPE_FATAL, +}; + +enum log_event_indicator { + WLAN_LOG_INDICATOR_UNUSED, + WLAN_LOG_INDICATOR_FRAMEWORK, + WLAN_LOG_INDICATOR_HOST_DRIVER, + WLAN_LOG_INDICATOR_FIRMWARE, +}; + +enum log_event_host_reason_code { + WLAN_LOG_REASON_CODE_UNUSED, + WLAN_LOG_REASON_COMMAND_UNSUCCESSFUL, + WLAN_LOG_REASON_ROAM_FAIL, + WLAN_LOG_REASON_THREAD_STUCK, + WLAN_LOG_REASON_DATA_STALL, + WLAN_LOG_REASON_SME_COMMAND_STUCK, + WLAN_LOG_REASON_ZERO_SCAN_RESULTS, + WLAN_LOG_REASON_QUEUE_FULL, + WLAN_LOG_REASON_POWER_COLLAPSE_FAIL, + WLAN_LOG_REASON_SSR_FAIL, + WLAN_LOG_REASON_DISCONNECT_FAIL, + WLAN_LOG_REASON_CLEAN_UP_FAIL, + WLAN_LOG_REASON_MALLOC_FAIL, + WLAN_LOG_REASON_VOS_MSG_UNDER_RUN, + WLAN_LOG_REASON_MSG_POST_FAIL, +}; + +typedef struct { + u32 is_fatal; + u32 indicator; + u32 reason_code; + u32 reserved; +} wlan_log_complete_event_t; + +typedef struct { + u32 reason; +} wlan_data_stall_event_t; + +wifi_error diag_message_handler(hal_info *info, nl_msg *msg); + +#endif /* __WIFI_HAL_WIFILOGGER_DIAG_H__ */ diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h b/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h new file mode 100644 index 0000000..86b198c --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h @@ -0,0 +1,516 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef WIFILOGGER_EVENT_DEFS_H +#define WIFILOGGER_EVENT_DEFS_H + +typedef enum { + EVENT_DROP_ID = 0, + + EVENT_WLAN_PE = 0x67A, /* 16 byte payload */ + + /* Events between 0x67b to 0x67f are not used */ + + EVENT_WLAN_ADD_BLOCK_ACK_SUCCESS = 0x67B, /* 11 byte payload */ + EVENT_WLAN_ADD_BLOCK_ACK_FAILED = 0x67C, /* 9 byte payload */ + EVENT_WLAN_BRINGUP_STATUS = 0x680, /* 12 byte payload */ + EVENT_WLAN_POWERSAVE_WOW = 0x682, /* 11 byte payload */ + + EVENT_WLAN_EXTSCAN_FEATURE_STARTED = 0xA8E, /* 240 byte payload */ + EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG = 0xA8F, /* 243 byte payload */ + EVENT_WLAN_EXTSCAN_CYCLE_STARTED = 0xA90, /* 12 byte payload */ + EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED = 0xA91, /* 12 byte payload */ + EVENT_WLAN_EXTSCAN_BUCKET_STARTED = 0xA92, /* 1 byte payload */ + EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED = 0xA93, /* 4 byte payload */ + EVENT_WLAN_ROAM_SCAN_STARTED = 0xA94, /* 128 byte payload */ + + + EVENT_WLAN_ROAM_SCAN_COMPLETE = 0xA95, + EVENT_WLAN_ROAM_CANDIDATE_FOUND = 0xA96, + EVENT_WLAN_ROAM_SCAN_CONFIG = 0xA97, + EVENT_WLAN_BT_COEX_BT_SCO_START = 0xA98, + EVENT_WLAN_BT_COEX_BT_SCO_STOP = 0xA99, + EVENT_WLAN_BT_COEX_BT_SCAN_START = 0xA9A, + EVENT_WLAN_BT_COEX_BT_SCAN_STOP = 0xA9B, + EVENT_WLAN_BT_COEX_BT_HID_START = 0xA9C, + EVENT_WLAN_BT_COEX_BT_HID_STOP = 0xA9D, + EVENT_WLAN_WAKE_LOCK = 0xAA2, /* 96 bytes payload */ + EVENT_WLAN_EAPOL = 0xA8D, /* 96 bytes payload */ + EVENT_WLAN_EXTSCAN_FEATURE_STOP = 0xAA3, + EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE = 0xAA4, + EVENT_WLAN_BEACON_EVENT = 0xAA6, + EVENT_WLAN_LOG_COMPLETE = 0xAA7, + EVENT_WLAN_LOW_RESOURCE_FAILURE = 0xABB, + EVENT_WLAN_POWERSAVE_WOW_STATS = 0xB33, /* 76 bytes payload */ + EVENT_WLAN_STA_KICKOUT = 0xB39, /* 11 bytes payload */ + EVENT_WLAN_STA_DATA_STALL = 0xB3A, + + EVENT_MAX_ID = 0x0FFF +} event_id_enum_type; + +typedef enum { + LOG_DROP_ID = 0, + LOG_WLAN_EXTSCAN_CAPABILITIES = 0x18F1, + LOG_WLAN_EXTSCAN_FEATURE_STARTED = 0x18F2, +} log_id_enum_type; + +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 = 10, + 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 = 20, + 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 = 30, + 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 = 40, + 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 = 50, + 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 = 60, + WLAN_PE_DIAG_CONNECTED, + WLAN_PE_DIAG_ASSOC_REQ_EVENT, + WLAN_PE_DIAG_AUTH_COMP_EVENT, + WLAN_PE_DIAG_ASSOC_COMP_EVENT, + WLAN_PE_DIAG_AUTH_START_EVENT, + WLAN_PE_DIAG_ASSOC_START_EVENT, + WLAN_PE_DIAG_REASSOC_START_EVENT, + WLAN_PE_DIAG_ROAM_AUTH_START_EVENT, + WLAN_PE_DIAG_ROAM_AUTH_COMP_EVENT, + WLAN_PE_DIAG_ROAM_ASSOC_START_EVENT = 70, + WLAN_PE_DIAG_ROAM_ASSOC_COMP_EVENT, + WLAN_PE_DIAG_SCAN_COMP_EVENT, + WLAN_PE_DIAG_SCAN_RES_FOUND_EVENT, + WLAN_PE_DIAG_ASSOC_TIMEOUT, + WLAN_PE_DIAG_AUTH_TIMEOUT, +} wlan_host_diag_event_type; + +typedef struct wlan_pe_event { + char bssid[6]; + u16 event_type; + u16 sme_state; + u16 mlm_state; + u16 status; + u16 reason_code; +} __attribute__((packed)) wlan_pe_event_t; + +typedef enum { + WLAN_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED = 0, + WLAN_DRIVER_EAPOL_FRAME_RECEIVED, +} wlan_eapol_event_type; + +#define EAPOL_MASK 0x8013 +#define EAPOL_M1_MASK 0x8000 +#define EAPOL_M2_MASK 0x0001 +#define EAPOL_M3_MASK 0x8013 +#define EAPOL_M4_MASK 0x0003 + +typedef struct wlan_eapol_event { + u8 event_sub_type; + u8 eapol_packet_type; + u16 eapol_key_info; + u16 eapol_rate; + u8 dest_addr[6]; + u8 src_addr[6]; +} __attribute__((packed)) wlan_eapol_event_t; + +/*EVENT_WLAN_EXTSCAN_FEATURE_STARTED */ +typedef struct wlan_ext_bucket { + u8 bucket_id; + u8 base_period_multiplier; + u16 min_dwell_time_active; + u16 max_dwell_time_active; + u16 min_dwell_time_passive; + u16 max_dwell_time_passive; + u8 num_channels; + u8 channel_offset; + u8 forwarding_flags; + u8 channel_band; + u32 notify_extscan_events; +} __attribute__((packed)) wlan_ext_bucket_t; + +typedef struct { + u32 base_period; + u32 max_iterations; + u32 forwarding_flags; + u32 configuration_flags; + u32 notify_extscan_events; + u32 scan_priority; + u32 max_bssids_per_scan_cycle; + u32 min_rssi; + u32 max_table_usage; + u32 min_dwell_time_active; + u32 max_dwell_time_active; + u32 min_dwell_time_passive; + u32 max_dwell_time_passive; + u32 min_rest_time; + u32 max_rest_time; + u32 n_probes; + u32 repeat_probe_time; + u32 probe_spacing_time; + u32 idle_time; + u32 max_scan_time; + u32 probe_delay; + u32 scan_ctrl_flags; + u32 burst_duration; + u32 num_buckets; + wlan_ext_bucket bucket_list[8]; +} __attribute__((packed)) wlan_ext_scan_feature_started_payload_type; +/*End EVENT_WLAN_EXTSCAN_FEATURE_STARTED*/ + +/*EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/ +typedef struct { + u8 bucket_id; + u16 scan_channels[40]; +} __attribute__((packed)) wlan_ext_bucket_channels; + +typedef struct { + wlan_ext_bucket_channels bucket_list[3]; +} __attribute__((packed)) wlan_ext_bucket_channel_config_payload_type; + +/*End EVENT_WLAN_EXTSCAN_FEATURE_CHANNEL_CONFIG*/ + +/*EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/ +typedef struct { + u32 scan_id; + u32 timer_tick; + u32 scheduled_bucket_mask; + u32 scan_cycle_count; +} __attribute__((packed)) wlan_ext_scan_cycle_started_payload_type; +/*End EVENT_WLAN_EXTSCAN_CYCLE_STARTED*/ + +/*EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/ +typedef struct { + u32 scan_id; + u32 timer_tick; + u32 scheduled_bucket_mask; + u32 scan_cycle_count; +} __attribute__((packed)) wlan_ext_scan_cycle_completed_payload_type; +/*End EVENT_WLAN_EXTSCAN_CYCLE_COMPLETED*/ + +/*EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/ +typedef struct { + u8 bucket_id; +} __attribute__((packed)) wlan_ext_scan_bucket_started_payload_type; +/*End EVENT_WLAN_EXTSCAN_BUCKET_STARTED*/ + +/*EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/ +typedef struct { + u8 bucket_id; +} __attribute__((packed)) wlan_ext_scan_bucket_completed_payload_type; +/*End EVENT_WLAN_EXTSCAN_BUCKET_COMPLETED*/ + +/*EVENT_WLAN_ROAM_SCAN_STARTED*/ +typedef struct { + u32 scan_id; + u32 roam_scan_flags; + u32 cur_rssi; + u16 scan_params[18]; + u16 scan_channels[40]; // first 40 channels only +} __attribute__((packed)) wlan_roam_scan_started_payload_type; +/*End EVENT_WLAN_ROAM_SCAN_STARTED*/ + +/*EVENT_WLAN_ROAM_SCAN_COMPLETE*/ +typedef struct { + u32 scan_id; + u32 reason; + u32 completion_flags; + u32 num_candidate; + u32 flags; +} __attribute__((packed)) wlan_roam_scan_complete_payload_type; +/*End EVENT_WLAN_ROAM_SCAN_COMPLETE*/ + +/*EVENT_WLAN_ROAM_CANDIDATE_FOUND*/ +typedef struct { + u8 channel; + u8 rssi; + u8 bssid[6]; + u8 ssid[33]; + u8 auth_mode; + u8 ucast_cipher; + u8 mcast_cipher; +} __attribute__((packed)) wlan_roam_candidate_found_payload_type; +/*End EVENT_WLAN_ROAM_CANDIDATE_FOUND*/ + +/*EVENT_WLAN_ROAM_SCAN_CONFIG*/ +typedef struct { + u32 flags; + u32 roam_scan_config[8]; +} __attribute__((packed)) wlan_roam_scan_config_payload_type; +/*End EVENT_WLAN_ROAM_SCAN_CONFIG*/ + +/* EVENT_WLAN_BT_COEX_BT_SCO_START */ +typedef struct { + u8 link_id; + u8 link_state; + u8 link_role; + u8 link_type; + u16 Tsco; + u8 Rsco; +} __attribute__((packed)) wlan_bt_coex_bt_sco_start_payload_type; +/* End EVENT_WLAN_BT_COEX_BT_SCO_START */ + +/* EVENT_WLAN_BT_COEX_BT_SCO_STOP */ +typedef struct { + u8 link_id; + u8 link_state; + u8 link_role; + u8 link_type; + u16 Tsco; + u8 Rsco; +} __attribute__((packed)) wlan_bt_coex_bt_sco_stop_payload_type; +/* End EVENT_WLAN_BT_COEX_BT_SCO_STOP */ + +/* EVENT_WLAN_BT_COEX_BT_SCAN_START */ +typedef struct { + u8 scan_type; + u8 scan_bitmap; +} __attribute__((packed)) wlan_bt_coex_bt_scan_start_payload_type; + +/* End EVENT_WLAN_BT_COEX_BT_SCAN_START */ + +/* EVENT_WLAN_BT_COEX_BT_SCAN_STOP */ +typedef struct { + u8 scan_type; + u8 scan_bitmap; +} __attribute__((packed)) wlan_bt_coex_bt_scan_stop_payload_type; +/* End EVENT_WLAN_BT_COEX_BT_SCAN_STOP */ + +/* EVENT_WIFI_BT_COEX_BT_HID_START */ +typedef struct { + u8 link_id; + u8 link_state; + u8 link_role; + u8 Tsniff; + u8 attempts; +} __attribute__((packed)) wlan_bt_coex_bt_hid_start_payload_type; +/* End EVENT_WIFI_BT_COEX_BT_HID_START */ + +/* EVENT_WIFI_BT_COEX_BT_HID_STOP */ +typedef struct { + u8 link_id; + u8 link_state; + u8 link_role; + u8 Tsniff; + u8 attempts; +} __attribute__((packed)) wlan_bt_coex_bt_hid_stop_payload_type; +/* End EVENT_WIFI_BT_COEX_BT_HID_STOP */ + +/* EVENT_WLAN_EXTSCAN_FEATURE_STOP */ +typedef struct { + u32 request_id; +} __attribute__((packed)) wlan_ext_scan_feature_stop_payload_type; +/* End EVENT_WLAN_EXTSCAN_FEATURE_STOP */ + +/* EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */ +typedef struct { + u32 request_id; + u32 table_type; + u32 entries_in_use; + u32 maximum_entries; + u32 scan_count_after_getResults; + u8 threshold_num_scans; +} __attribute__((packed)) wlan_ext_scan_results_available_payload_type; +/* End EVENT_WLAN_EXTSCAN_RESULTS_AVAILABLE */ + +/* Log LOG_WLAN_EXTSCAN_CAPABILITIES */ +typedef struct { + u32 header; + u32 request_id; + u32 requestor_id; + u32 vdev_id; + u32 num_extscan_cache_tables; + u32 num_wlan_change_monitor_tables; + u32 num_hotlist_monitor_tables; + u32 rtt_one_sided_supported; + u32 rtt_11v_supported; + u32 rtt_ftm_supported; + u32 num_extscan_cache_capabilities; + u32 num_extscan_wlan_change_capabilities; + u32 num_extscan_hotlist_capabilities; + u32 num_roam_ssid_whitelist; + u32 num_roam_bssid_blacklist; + u32 num_roam_bssid_preferred_list; + u32 num_extscan_hotlist_ssid; + u32 num_epno_networks; +} __attribute__((packed)) wlan_extscan_capabilities_event_fixed_param; + +typedef struct { + u32 header; + u32 table_id; + u32 scan_cache_entry_size; + u32 max_scan_cache_entries; + u32 max_buckets; + u32 max_bssid_per_scan; + u32 max_table_usage_threshold; +} __attribute__((packed)) wlan_extscan_cache_capabilities; + +typedef struct { + u32 tlv_header; + u32 table_id; + u32 wlan_hotlist_entry_size; + u32 max_hotlist_entries; +} __attribute__((packed)) wlan_extscan_hotlist_monitor_capabilities; + +typedef struct { + u32 request_id; + wlan_extscan_capabilities_event_fixed_param extscan_capabilities; + wlan_extscan_cache_capabilities extscan_cache_capabilities; + wlan_extscan_hotlist_monitor_capabilities extscan_hotlist_monitor_capabilities; +} __attribute__((packed)) wlan_ext_scan_capabilities_payload_type; +/* End LOG_WLAN_EXTSCAN_CAPABILITIES */ + +/* EVENT_WLAN_BEACON_RECEIVED */ +typedef struct { + u8 bssid[6]; + u32 beacon_rssi; +} __attribute__((packed)) wlan_beacon_received_payload_type; +/* End EVENT_WLAN_BEACON_RECEIVED */ + +typedef struct { + u8 ucBaPeerMac[6]; + u8 ucBaTid; + u8 ucBaBufferSize; + u16 ucBaSSN; + u8 fInitiator; +} __attribute__((packed)) wlan_add_block_ack_success_payload_type; + +/* EVENT_WLAN_ADD_BLOCK_ACK_FAILED */ +typedef struct { + u8 ucBaPeerMac[6]; + u8 ucBaTid; + u8 ucReasonCode; + u8 fInitiator; +} __attribute__((packed)) wlan_add_block_ack_failed_payload_type; + +typedef enum +{ + WIFI_EVENT_MEMORY_FAILURE, +} resource_failure_type; + +typedef struct wlan_low_resource_failure_event +{ + resource_failure_type event_sub_type; +} __attribute__((packed)) wlan_low_resource_failure_event_t; + +/* EVENT_WLAN_POWERSAVE_WOW */ +typedef struct { + u8 event_subtype; + u8 wow_type; + u8 wow_magic_pattern[6]; + u8 wow_del_ptrn_id; + u8 wow_wakeup_cause; + u8 wow_wakeup_cause_pbm_ptrn_id; +} __attribute__((packed)) wlan_wow_payload_t; + +/* EVENT_WLAN_POWERSAVE_WOW_STATS */ +typedef struct { + u32 wow_ucast_wake_up_count; + u32 wow_bcast_wake_up_count; + u32 wow_ipv4_mcast_wake_up_count; + u32 wow_ipv6_mcast_wake_up_count; + u32 wow_ipv6_mcast_ra_stats; + u32 wow_ipv6_mcast_ns_stats; + u32 wow_ipv6_mcast_na_stats; + u32 wow_pno_match_wake_up_count; + u32 wow_pno_complete_wake_up_count; + u32 wow_gscan_wake_up_count; + u32 wow_low_rssi_wake_up_count; + u32 wow_rssi_breach_wake_up_count; + u32 wow_icmpv4_count; + u32 wow_icmpv6_count; + u32 wow_oem_response_wake_up_count; + u32 Reserved_1; + u32 Reserved_2; + u32 Reserved_3; + u32 Reserved_4; +} __attribute__((packed)) wlan_wow_stats_t; + +/* EVENT_WLAN_STA_KICKOUT */ +typedef struct { + u32 reasoncode; + u8 peer_mac[6]; + u8 vdev_id; +} __attribute__((packed)) wlan_kickout_t; + +/* EVENT_WLAN_BRINGUP_STATUS */ +typedef struct { + u16 wlan_status; + u8 driver_version[10]; +} __attribute__((packed)) wlan_status_payload_t; + +#endif /* WIFILOGGER_EVENT_DEFS_H */ diff --git a/wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h b/wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h new file mode 100644 index 0000000..422abd3 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h @@ -0,0 +1,135 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__ +#define __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__ + +#include "common.h" + +typedef struct { + u8 Tsniff; + u8 attempts; +} bt_coex_hid_vendor_data_t; + +typedef struct { + u32 timer_tick; + u32 scheduled_bucket_mask; + u32 scan_cycle_count; +} __attribute__((packed)) ext_scan_cycle_vendor_data_t; + +typedef struct { + u32 table_type; + u32 entries_in_use; + u32 maximum_entries; + u32 scan_count_after_getResults; + u8 threshold_num_scans; +} __attribute__((packed)) ext_scan_results_available_vendor_data_t; + +typedef struct { + u32 roam_scan_flags; + u32 cur_rssi; + u16 scan_params[18]; + u16 scan_channels[40]; // first 40 channels only +} __attribute__((packed)) roam_scan_started_vendor_data_t; + +typedef struct { + u32 reason; + u32 completion_flags; + u32 num_candidate; + u32 flags; +} __attribute__((packed)) roam_scan_complete_vendor_data_t; + +typedef struct { + u8 ssid[33]; + u8 auth_mode; + u8 ucast_cipher; + u8 mcast_cipher; +} __attribute__((packed)) roam_candidate_found_vendor_data_t; + +typedef struct { + u32 flags; + u32 roam_scan_config[8]; +} __attribute__((packed)) roam_scan_config_vendor_data_t; + +typedef struct { + u8 scan_type; + u8 scan_bitmap; +} __attribute__((packed)) bt_coex_bt_scan_start_vendor_data_t; + +typedef struct { + u8 scan_type; + u8 scan_bitmap; +} __attribute__((packed)) bt_coex_bt_scan_stop_vendor_data_t; + +typedef struct { + u16 sme_state; + u16 mlm_state; +} __attribute__((packed)) pe_event_vendor_data_t; + +typedef enum { + ADDBA_SUCCESS = 0, + ADDBA_FAILURE = -1, +} addba_status_t; + +typedef struct { + u8 ucBaTid; + u8 ucBaBufferSize; + u16 ucBaSSN; + u8 fInitiator; +} __attribute__((packed)) addba_success_vendor_data_t; + +typedef struct { + u8 ucBaTid; + u8 fInitiator; +} __attribute__((packed)) addba_failed_vendor_data_t; + +typedef struct { + u32 hotlist_mon_table_id; + u32 wlan_hotlist_entry_size; + u32 cache_cap_table_id; + u32 max_scan_cache_entries; + u32 requestor_id; + u32 vdev_id; + u32 num_extscan_cache_tables; + u32 num_wlan_change_monitor_tables; + u32 num_hotlist_monitor_tables; + u32 rtt_one_sided_supported; + u32 rtt_11v_supported; + u32 rtt_ftm_supported; + u32 num_extscan_cache_capabilities; + u32 num_extscan_wlan_change_capabilities; + u32 num_extscan_hotlist_capabilities; + u32 num_roam_bssid_blacklist; + u32 num_roam_bssid_preferred_list; +} __attribute__((packed)) gscan_capabilities_vendor_data_t; + +typedef struct +{ + resource_failure_type event_sub_type; +} __attribute__((packed)) resource_failure_vendor_data_t; +#endif /* __WIFI_HAL_WIFILOGGER_VENDOR_EVENTS_H__ */ diff --git a/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h b/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h new file mode 100644 index 0000000..9361821 --- /dev/null +++ b/wcn6740/qcwcn/wifi_hal/wifiloggercmd.h @@ -0,0 +1,120 @@ +/* Copyright (c) 2015, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef __WIFI_HAL_WIFILOGGER_COMMAND_H__ +#define __WIFI_HAL_WIFILOGGER_COMMAND_H__ + +#include "common.h" +#include "cpp_bindings.h" +#include "wifi_logger.h" +#include "wifilogger_diag.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#define POWER_EVENTS_RB_BUF_SIZE 2048 +#define POWER_EVENTS_NUM_BUFS 4 + +#define CONNECTIVITY_EVENTS_RB_BUF_SIZE 4096 +#define CONNECTIVITY_EVENTS_NUM_BUFS 4 + +#define PKT_STATS_RB_BUF_SIZE 4096 +#define PKT_STATS_NUM_BUFS 32 + +#define DRIVER_PRINTS_RB_BUF_SIZE 4096 +#define DRIVER_PRINTS_NUM_BUFS 128 + +#define FIRMWARE_PRINTS_RB_BUF_SIZE 32768 +#define FIRMWARE_PRINTS_NUM_BUFS 16 + +#define LOGGER_RING_BUFFER (WIFI_LOGGER_CONNECT_EVENT_SUPPORTED \ + | WIFI_LOGGER_POWER_EVENT_SUPPORTED \ + | WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED) + +enum rb_info_indices { + POWER_EVENTS_RB_ID = 0, + CONNECTIVITY_EVENTS_RB_ID = 1, + PKT_STATS_RB_ID = 2, + DRIVER_PRINTS_RB_ID = 3, + FIRMWARE_PRINTS_RB_ID = 4, +}; + +typedef struct { + void (*on_firmware_memory_dump) (char *buffer, + int buffer_size); + +} WifiLoggerCallbackHandler; + + +class WifiLoggerCommand : public WifiVendorCommand +{ +private: + WifiLoggerCallbackHandler mHandler; + char *mVersion; + int mVersionLen; + u32 *mSupportedSet; + int mRequestId; + bool mWaitforRsp; + bool mMoreData; + WLAN_DRIVER_WAKE_REASON_CNT *mGetWakeStats; +public: + + WifiLoggerCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd); + + static WifiLoggerCommand* instance(wifi_handle handle); + virtual ~WifiLoggerCommand(); + + // This function implements creation of WifiLogger specific Request + // based on the request type + virtual wifi_error create(); + virtual wifi_error requestEvent(); + virtual wifi_error requestResponse(); + virtual int handleResponse(WifiEvent &reply); + virtual int handleEvent(WifiEvent &event); + wifi_error setCallbackHandler(WifiLoggerCallbackHandler nHandler); + virtual void unregisterHandler(u32 subCmd); + + /* Takes wait time in seconds. */ + virtual wifi_error timed_wait(u16 wait_time); + virtual void waitForRsp(bool wait); + virtual void setVersionInfo(char *buffer, int buffer_size); + virtual void setFeatureSet(u32 *support); + virtual void getWakeStatsRspParams( + WLAN_DRIVER_WAKE_REASON_CNT *wifi_wake_reason_cnt); +}; +void rb_timerhandler(hal_info *info); +wifi_error wifi_logger_ring_buffers_init(hal_info *info); +void wifi_logger_ring_buffers_deinit(hal_info *info); +void push_out_all_ring_buffers(hal_info *info); +void send_alert(hal_info *info, int reason_code); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __WIFI_HAL_WIFILOGGER_COMMAND_H__ */ diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk b/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk new file mode 100644 index 0000000..e90d9be --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk @@ -0,0 +1,76 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH := $(call my-dir) + +ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X) + +ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),) + CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y +endif + +WPA_SUPPL_DIR := external/wpa_supplicant_8 +WPA_SRC_FILE := + +include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config + +WPA_SUPPL_DIR_INCLUDE := $(WPA_SUPPL_DIR)/src \ + $(WPA_SUPPL_DIR)/src/common \ + $(WPA_SUPPL_DIR)/src/drivers \ + $(WPA_SUPPL_DIR)/src/l2_packet \ + $(WPA_SUPPL_DIR)/src/utils \ + $(WPA_SUPPL_DIR)/src/wps \ + $(WPA_SUPPL_DIR)/src/ap \ + $(WPA_SUPPL_DIR)/wpa_supplicant + +ifdef CONFIG_DRIVER_NL80211 +WPA_SUPPL_DIR_INCLUDE += external/libnl/include +WPA_SRC_FILE += driver_cmd_nl80211_extn.c \ + driver_cmd_nl80211.c +endif + +ifeq ($(TARGET_ARCH),arm) +# To force sizeof(enum) = 4 +L_CFLAGS += -mabi=aapcs-linux +endif + +ifdef CONFIG_ANDROID_LOG +L_CFLAGS += -DCONFIG_ANDROID_LOG +endif + +ifdef CONFIG_P2P +L_CFLAGS += -DCONFIG_P2P +endif + +L_CFLAGS += -Werror + +######################## + +include $(CLEAR_VARS) +LOCAL_MODULE := lib_driver_cmd_qcwcn +LOCAL_SHARED_LIBRARIES := libc libcutils +ifneq ($(wildcard external/libnl),) +LOCAL_SHARED_LIBRARIES += libnl +endif +LOCAL_SHARED_LIBRARIES += libdl +LOCAL_CFLAGS := $(L_CFLAGS) -Wall +LOCAL_SRC_FILES := $(WPA_SRC_FILE) +LOCAL_C_INCLUDES := $(WPA_SUPPL_DIR_INCLUDE) +LOCAL_VENDOR_MODULE := true +include $(BUILD_STATIC_LIBRARY) + +######################## + +endif diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD b/wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am new file mode 100644 index 0000000..e314452 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am @@ -0,0 +1,26 @@ +# Makefile.am - Automake script for wpa_supplicant_8_lib +ACLOCAL_AMFLAGS = -I m4 + +AM_CFLAGS = -Wall + +if DEBUG +AM_CFLAGS += -g +else +AM_CFLAGS += -O2 +endif + +AM_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast \ + -Wno-maybe-uninitialized -Wno-parentheses \ + -DCONFIG_P2P + +h_sources = driver_cmd_nl80211_extn.h +library_includedir = $(pkgincludedir) +library_include_HEADERS = $(h_sources) + +libwpa_supplicant_8_lib_la_SOURCES = driver_cmd_nl80211.c +libwpa_supplicant_8_lib_la_SOURCES += driver_cmd_nl80211_extn.c +libwpa_supplicant_8_lib_la_CFLAGS = ${AM_CFLAGS} ${LIBNL_CFLAGS} +libwpa_supplicant_8_lib_la_LIBADD = ${LIBNL_LIBS} +lib_LTLIBRARIES = libwpa_supplicant_8_lib.la + +pkgconfigdir = $(libdir)/pkgconfig diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE b/wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE new file mode 100644 index 0000000..f9d25ea --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE @@ -0,0 +1,43 @@ + +Copyright (c) 2005-2010, The Android Open Source Project +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 The Android Open Source Project 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 AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER 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. + + * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi> + * Copyright (c) 2003-2004, Instant802 Networks, Inc. + * Copyright (c) 2005-2006, Devicescape Software, Inc. + * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net> + * Copyright (c) 2009-2010, Atheros Communications + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac new file mode 100644 index 0000000..2be9651 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac @@ -0,0 +1,76 @@ +# -*- Autoconf -*- +# configure.ac -- Autoconf script for qcacld-tools +# + +AC_PREREQ(2.61) +AC_INIT([wpa_supplicant_8_lib], 1.0.0) +AM_INIT_AUTOMAKE([foreign]) +AM_MAINTAINER_MODE +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) +LT_INIT + +# 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 +PKG_PROG_PKG_CONFIG + +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]) + +has_libnl_ver=0 +# libnl-2 provides only libnl-2.0.pc file, so we check for separate libnl-genl-3.0.pc +# pkg-config file just for libnl-3.0 case. +# +PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.0 libnl-genl-3.0 >= 3.0], [has_libnl_ver=3], [ + PKG_CHECK_MODULES([LIBNL], [libnl-2.0 >= 2.0], [has_libnl_ver=2], [ + PKG_CHECK_MODULES([LIBNL], [libnl-1], [has_libnl_ver=1], [has_libnl_ver=0])])]) + +if (test "$has_libnl_ver" -eq 0); then + AC_MSG_ERROR(libnl and libnl-genl are required but were not found) +fi + +if (test "$has_libnl_ver" -gt 1); then + AC_DEFINE([HAVE_LIBNL20], [1], [Define if you have libnl-2.0 or higher]) +fi + +if (test "$has_libnl_ver" -gt 2); then + AC_DEFINE([HAVE_LIBNL30], [1], [Define if you have libnl-3.0 or higher]) +fi + +AC_SUBST([LIBNL_CFLAGS]) +AC_SUBST([LIBNL_LIBS]) + +# 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 +]) +AC_OUTPUT diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c new file mode 100644 index 0000000..7315a54 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c @@ -0,0 +1,5758 @@ +/* + * Driver interaction with extended Linux CFG8021 + * + * 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. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include "includes.h" +#include <sys/types.h> +#include <fcntl.h> +#include <net/if.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <netlink/object-api.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <linux/pkt_sched.h> + +#include "common.h" +#include "linux_ioctl.h" +#include "driver_nl80211.h" +#include "wpa_supplicant_i.h" +#include "config.h" +#include "wpa_driver_common_lib.h" +#include "ap/hostapd.h" +#include "ap/sta_info.h" +#ifdef LINUX_EMBEDDED +#include <sys/ioctl.h> +#endif +#if defined(ANDROID) || defined(LINUX_EMBEDDED) +#include "android_drv.h" +#endif +#include "driver_cmd_nl80211_extn.h" + +#define WPA_PS_ENABLED 0 +#define WPA_PS_DISABLED 1 +#define UNUSED(x) (void)(x) +#define NL80211_ATTR_MAX_INTERNAL 256 +#define CSI_STATUS_REJECTED -1 +#define CSI_STATUS_SUCCESS 0 +#define ENHANCED_CFR_VER 2 +#define CSI_GROUP_BITMAP 1 +#define CSI_DEFAULT_GROUP_ID 0 +#define CSI_FC_STYPE_BEACON 8 +#define CSI_MGMT_BEACON (1<<WLAN_FC_STYPE_BEACON) + +#define TWT_SETUP_WAKE_INTVL_MANTISSA_MAX 0xFFFF +#define TWT_SETUP_WAKE_DURATION_MAX 0xFF +#define TWT_SETUP_WAKE_INTVL_EXP_MAX 31 +#define TWT_WAKE_INTERVAL_TU_FACTOR 1024 + +#define TWT_SETUP_STR "twt_session_setup" +#define TWT_TERMINATE_STR "twt_session_terminate" +#define TWT_PAUSE_STR "twt_session_pause" +#define TWT_RESUME_STR "twt_session_resume" +#define TWT_NUDGE_STR "twt_session_nudge" +#define TWT_GET_PARAMS_STR "twt_session_get_params" +#define TWT_GET_STATS_STR "twt_session_get_stats" +#define TWT_CLEAR_STATS_STR "twt_session_clear_stats" +#define TWT_GET_CAP_STR "twt_get_capability" +#define TWT_SET_PARAM_STR "twt_set_param" + +#define TWT_SETUP_STRLEN strlen(TWT_SETUP_STR) +#define TWT_TERMINATE_STR_LEN strlen(TWT_TERMINATE_STR) +#define TWT_PAUSE_STR_LEN strlen(TWT_PAUSE_STR) +#define TWT_RESUME_STR_LEN strlen(TWT_RESUME_STR) +#define TWT_NUDGE_STR_LEN strlen(TWT_NUDGE_STR) +#define TWT_GET_PARAMS_STR_LEN strlen(TWT_GET_PARAMS_STR) +#define TWT_GET_STATS_STR_LEN strlen(TWT_GET_STATS_STR) +#define TWT_CLEAR_STATS_STR_LEN strlen(TWT_CLEAR_STATS_STR) +#define TWT_GET_CAP_STR_LEN strlen(TWT_GET_CAP_STR) +#define TWT_SET_PARAM_STR_LEN strlen(TWT_SET_PARAM_STR) + +#define TWT_CMD_NOT_EXIST -EINVAL +#define DEFAULT_IFNAME "wlan0" +#define TWT_RESP_BUF_LEN 512 + +#define SINGLE_SPACE_LEN 1 +#define SINGLE_DIGIT_LEN 1 + +#define DIALOG_ID_STR "dialog_id" +#define REQ_TYPE_STR "req_type" +#define TRIG_TYPE_STR "trig_type" +#define FLOW_TYPE_STR "flow_type" +#define WAKE_INTR_EXP_STR "wake_intr_exp" +#define PROTECTION_STR "protection" +#define WAKE_TIME_STR "wake_time" +#define WAKE_DUR_STR "wake_dur" +#define WAKE_INTR_MANTISSA_STR "wake_intr_mantissa" +#define BROADCAST_STR "broadcast" +#define MIN_WAKE_INTVL_STR "min_wake_intvl" +#define MAX_WAKE_INTVL_STR "max_wake_intvl" +#define MIN_WAKE_DUR_STR "min_wake_duration" +#define MAX_WAKE_DUR_STR "max_wake_duration" +#define NEXT_TWT_STR "next_twt" +#define NEXT2_TWT_STR "next2_twt" +#define NEXT_TWT_SIZE_STR "next_twt_size" +#define PAUSE_DURATION_STR "pause_duration" +#define WAKE_TSF_STR "wake_tsf" +#define ANNOUNCE_TIMEOUT_STR "announce_timeout" +#define AP_AC_VALUE_STR "ap_ac_value" +#define MAC_ADDRESS_STR "mac_addr" + +#define DIALOG_ID_STR_LEN strlen(DIALOG_ID_STR) +#define REQ_TYPE_STR_LEN strlen(REQ_TYPE_STR) +#define TRIG_TYPE_STR_LEN strlen(TRIG_TYPE_STR) +#define FLOW_TYPE_STR_LEN strlen(FLOW_TYPE_STR) +#define WAKE_INTR_EXP_STR_LEN strlen(WAKE_INTR_EXP_STR) +#define PROTECTION_STR_LEN strlen(PROTECTION_STR) +#define WAKE_TIME_STR_LEN strlen(WAKE_TIME_STR) +#define WAKE_DUR_STR_LEN strlen(WAKE_DUR_STR) +#define WAKE_INTR_MANTISSA_STR_LEN strlen(WAKE_INTR_MANTISSA_STR) +#define BROADCAST_STR_LEN strlen(BROADCAST_STR) +#define MIN_WAKE_INTVL_STR_LEN strlen(MIN_WAKE_INTVL_STR) +#define MAX_WAKE_INTVL_STR_LEN strlen(MAX_WAKE_INTVL_STR) +#define MIN_WAKE_DUR_STR_LEN strlen(MIN_WAKE_DUR_STR) +#define MAX_WAKE_DUR_STR_LEN strlen(MAX_WAKE_DUR_STR) +#define NEXT_TWT_STR_LEN strlen(NEXT_TWT_STR) +#define NEXT2_TWT_STR_LEN strlen(NEXT2_TWT_STR) +#define NEXT_TWT_SIZE_STR_LEN strlen(NEXT_TWT_SIZE_STR) +#define PAUSE_DURATION_STR_LEN strlen(PAUSE_DURATION_STR) +#define WAKE_TSF_STR_LEN strlen(WAKE_TSF_STR) +#define ANNOUNCE_TIMEOUT_STR_LEN strlen(ANNOUNCE_TIMEOUT_STR) +#define AP_AC_VALUE_STR_LEN strlen(AP_AC_VALUE_STR) +#define MAC_ADDR_STR_LEN strlen(MAC_ADDRESS_STR) + +#define MAC_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ADDR_ARRAY(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] + +#define TWT_CTRL_EVENT "CTRL-EVENT-TWT" +#define TWT_SETUP_RESP "CTRL-EVENT-TWT SETUP" +#define TWT_TEARDOWN_RESP "CTRL-EVENT-TWT TERMINATE" +#define TWT_PAUSE_RESP "CTRL-EVENT-TWT PAUSE" +#define TWT_RESUME_RESP "CTRL-EVENT-TWT RESUME" +#define TWT_NOTIFY_RESP "CTRL-EVENT-TWT NOTIFY" +#define TWT_SETUP_RESP_LEN strlen(TWT_SETUP_RESP) +#define TWT_TEARDOWN_RESP_LEN strlen(TWT_TEARDOWN_RESP) +#define TWT_PAUSE_RESP_LEN strlen(TWT_PAUSE_RESP) +#define TWT_RESUME_RESP_LEN strlen(TWT_RESUME_RESP) +#define TWT_NOTIFY_RESP_LEN strlen(TWT_NOTIFY_RESP) + +static int twt_async_support = -1; + +struct twt_setup_parameters { + u8 dialog_id; + u8 req_type; + u8 trig_type; + u8 flow_type; + u8 wake_intr_exp; + u8 protection; + u32 wake_time; + u32 wake_dur; + u32 wake_intr_mantissa; + u8 bcast; + u32 min_wake_intvl; + u32 max_wake_intvl; + u32 min_wake_duration; + u32 max_wake_duration; + u64 wake_tsf; + u32 announce_timeout_us; +}; + +struct twt_resume_parameters { + u8 dialog_id; + u8 next_twt; + u32 next2_twt; + u32 next_twt_size; +}; + +struct twt_nudge_parameters { + u8 dialog_id; + u32 wake_time; + u32 next_twt_size; +}; + +struct twt_set_parameters { + u8 ap_ac_value; +}; + +struct twt_resp_info { + char *reply_buf; + int reply_buf_len; + enum qca_wlan_twt_operation twt_oper; + struct wpa_driver_nl80211_data *drv; +}; + + +static int wpa_driver_twt_async_resp_event(struct wpa_driver_nl80211_data *drv, + u32 vendor_id, u32 subcmd, u8 *data, size_t len); + +/* ============ nl80211 driver extensions =========== */ +enum csi_state { + CSI_STATE_STOP = 0, + CSI_STATE_START, +}; + +struct csi_global_params { + struct i802_bss *bss; + enum csi_state current_state; + char connected_bssid[MAC_ADDR_LEN]; + int transport_mode; +}; + +static struct csi_global_params g_csi_param = {0}; + +static wpa_driver_oem_cb_table_t *oem_cb_table = NULL; + +#define MCC_QUOTA_MIN 10 +#define MCC_QUOTA_MAX 90 +/* Only one quota entry for now */ +#define MCC_QUOTA_ENTRIES_MAX 1 + +struct mcc_quota { + uint32_t if_idx; + uint32_t quota; +}; + + +static char *get_next_arg(char *cmd) +{ + char *pos = cmd; + + while (*pos != ' ' && *pos != '\0') + pos++; + + return pos; +} + +static int wpa_driver_cmd_set_ani_level(struct i802_bss *bss, int mode, int ofdmlvl) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg = NULL; + struct nlattr *params = NULL; + int ret = 0; + + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) || + !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_SETTING, mode)) { + nlmsg_free(msg); + return -1; + } + if(mode == QCA_WLAN_ANI_SETTING_FIXED) { + if(nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL, sizeof(int32_t), &ofdmlvl)){ + nlmsg_free(msg); + return -1; + } + } + nla_nest_end(msg, params); + ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); + if (!ret) + return 0; + wpa_printf(MSG_ERROR, "%s: Failed set_ani_level, ofdmlvl=%d, ret=%d", + __FUNCTION__, ofdmlvl, ret); + return ret; +} + +static int wpa_driver_cmd_set_congestion_report(struct i802_bss *bss, char *cmd) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *params = NULL; + char *endptr = NULL; + int ret; + int enable = -1, threshold = -1, interval = -1; + + wpa_printf(MSG_INFO, "%s enter", __FUNCTION__); + + enable = strtol(cmd, &endptr, 10); + if (enable != 0 && enable != 1) { + wpa_printf(MSG_ERROR, "%s: invalid enable arg %d", __FUNCTION__, enable); + return -EINVAL; + } + + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS) || + !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE, + QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT) || + nla_put_u8(msg, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE, + enable)) { + nlmsg_free(msg); + return -1; + } + if (enable == 1) { + if (!(*endptr) || + ((threshold = strtol(endptr, &endptr, 10)) < 0 || threshold > 100) || + !(*endptr) || + ((interval = strtol(endptr, &endptr, 10)) < 1 || interval > 30)) { + wpa_printf(MSG_ERROR, "%s: args less or invalid", __FUNCTION__); + nlmsg_free(msg); + return -EINVAL; + } + if (nla_put_u8(msg, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD, + threshold) || nla_put_u8(msg, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL, + interval)) { + nlmsg_free(msg); + return -1; + } + } + nla_nest_end(msg, params); + ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); + wpa_printf(MSG_INFO, "%s: set congestion report: enable=%d, threshold=%d," + "interval=%d", __FUNCTION__, enable, threshold, interval); + if (!ret) + return 0; + wpa_printf(MSG_ERROR, "%s: Failed set congestion report, ret=%d", __FUNCTION__, ret); + return ret; +} + +static int wpa_driver_cmd_set_tx_power(struct i802_bss *bss, char *cmd) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + char *endptr = NULL; + int ret; + int dbm, mbm; + + wpa_printf(MSG_INFO, "%s enter: dbm=%s", __FUNCTION__, cmd); + + dbm = strtol(cmd, &endptr, 10); + if (*endptr || dbm < 0) { + wpa_printf(MSG_ERROR, "%s: invalid dbm %d", __FUNCTION__, dbm); + return -EINVAL; + } + mbm = dbm * 100; + if (mbm < 0) { // integer overflow + wpa_printf(MSG_ERROR, "%s: invalid mbm %d", __FUNCTION__, mbm); + return -EINVAL; + } + + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_WIPHY)) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, + NL80211_TX_POWER_LIMITED) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm)) { + nlmsg_free(msg); + return -ENOBUFS; + } + + ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL); + if (!ret) + return 0; + + wpa_printf(MSG_ERROR, "%s: Failed set_tx_power dbm=%d, ret=%d", + __FUNCTION__, dbm, ret); + return ret; +} + +/* Return type for setBand*/ +enum { + SEND_CHANNEL_CHANGE_EVENT = 0, + DO_NOT_SEND_CHANNEL_CHANGE_EVENT, +}; + +typedef struct android_wifi_priv_cmd { + char *buf; + int used_len; + int total_len; +} android_wifi_priv_cmd; + +static int drv_errors = 0; + +static void wpa_driver_notify_country_change(void *ctx, char *cmd) +{ + if ((os_strncasecmp(cmd, "COUNTRY", 7) == 0) || + (os_strncasecmp(cmd, "SETBAND", 7) == 0)) { + union wpa_event_data event; + + os_memset(&event, 0, sizeof(event)); + event.channel_list_changed.initiator = REGDOM_SET_BY_USER; + if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) { + event.channel_list_changed.type = REGDOM_TYPE_COUNTRY; + if (os_strlen(cmd) > 9) { + event.channel_list_changed.alpha2[0] = cmd[8]; + event.channel_list_changed.alpha2[1] = cmd[9]; + } + } else { + event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN; + } + wpa_supplicant_event(ctx, EVENT_CHANNEL_LIST_CHANGED, &event); + } +} + +static struct remote_sta_info g_sta_info = {0}; +static struct bss_info g_bss_info = {0}; + +static struct nl_msg *prepare_nlmsg(struct wpa_driver_nl80211_data *drv, + char *ifname, int cmdid, int subcmd, + int flag) +{ + int res; + struct nl_msg *nlmsg = nlmsg_alloc(); + int ifindex; + + if (nlmsg == NULL) { + wpa_printf(MSG_ERROR,"Out of memory"); + return NULL; + } + + genlmsg_put(nlmsg, /* pid = */ 0, /* seq = */ 0, + drv->global->nl80211_id, 0, flag, cmdid, 0); + + if (cmdid == NL80211_CMD_VENDOR) { + res = nla_put_u32(nlmsg, NL80211_ATTR_VENDOR_ID, OUI_QCA); + if (res < 0) { + wpa_printf(MSG_ERROR,"Failed to put vendor id"); + goto cleanup; + } + + res = nla_put_u32(nlmsg, NL80211_ATTR_VENDOR_SUBCMD, subcmd); + if (res < 0) { + wpa_printf(MSG_ERROR,"Failed to put vendor sub command"); + goto cleanup; + } + } + + if (ifname && (strlen(ifname) > 0)) + ifindex = if_nametoindex(ifname); + else + ifindex = if_nametoindex(DEFAULT_IFNAME); + + if (nla_put_u32(nlmsg, NL80211_ATTR_IFINDEX, ifindex) != 0) { + wpa_printf(MSG_ERROR,"Failed to get iface index for iface: %s", ifname); + goto cleanup; + } + + return nlmsg; + +cleanup: + if (nlmsg) + nlmsg_free(nlmsg); + return NULL; +} + +static struct nl_msg *prepare_vendor_nlmsg(struct wpa_driver_nl80211_data *drv, + char *ifname, int subcmd) +{ + return prepare_nlmsg(drv, ifname, NL80211_CMD_VENDOR, subcmd, 0); +} + +static int parse_station_info(struct resp_info *info, struct nlattr *vendata, + int datalen) +{ + struct nlattr *tb_vendor[GET_STATION_INFO_MAX + 1]; + struct nlattr *attr, *attr1, *attr2; + u8 *beacon_ies = NULL; + size_t beacon_ies_len = 0; + u8 seg1; + + g_bss_info.oui[0] = (OUI_QCA) & 0xFF; + g_bss_info.oui[1] = ((OUI_QCA)>>8) & 0xFF; + g_bss_info.oui[2] = ((OUI_QCA)>>16) & 0xFF; + + nla_parse(tb_vendor, GET_STATION_INFO_MAX, + vendata, datalen, NULL); + + attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR]; + if (attr) { + struct nlattr *tb1[NL80211_ATTR_MAX + 1]; + + nla_parse(tb1, NL80211_ATTR_MAX, nla_data(attr), + nla_len(attr), NULL); + if (tb1[NL80211_ATTR_SSID] && + (nla_len(tb1[NL80211_ATTR_SSID]) <= MAX_SSID_LEN)) { + os_memcpy(g_bss_info.ssid, nla_data(tb1[NL80211_ATTR_SSID]), + nla_len(tb1[NL80211_ATTR_SSID])); + g_bss_info.ssid[nla_len(tb1[NL80211_ATTR_SSID])] = '\0'; + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_SSID not found"); + } + if (tb1[NL80211_ATTR_MAC]) { + os_memcpy(g_bss_info.oui, nla_data(tb1[NL80211_ATTR_MAC]), OUI_LEN); + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_MAC not found"); + } + if (tb1[NL80211_ATTR_SURVEY_INFO]) { + struct nlattr *tb2[NL80211_SURVEY_INFO_MAX + 1]; + + nla_parse(tb2, NL80211_SURVEY_INFO_MAX, + nla_data(tb1[NL80211_ATTR_SURVEY_INFO]), + nla_len(tb1[NL80211_ATTR_SURVEY_INFO]), NULL); + if (tb2[NL80211_SURVEY_INFO_FREQUENCY]) { + g_bss_info.channel = + nla_get_u32(tb2[NL80211_SURVEY_INFO_FREQUENCY]); + } else { + wpa_printf(MSG_ERROR, + "NL80211_SURVEY_INFO_FREQUENCY not found"); + } + if (tb2[NL80211_SURVEY_INFO_NOISE]) { + g_bss_info.noise = + nla_get_u8(tb2[NL80211_SURVEY_INFO_NOISE]); + g_bss_info.noise -= 100; + } else { + wpa_printf(MSG_ERROR,"NL80211_SURVEY_INFO_NOISE not found"); + } + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_SURVEY_INFO not found"); + } + + if (tb1[NL80211_ATTR_STA_INFO]) { + struct nlattr *tb2[NL80211_STA_INFO_MAX + 1]; + + nla_parse(tb2, NL80211_STA_INFO_MAX, + nla_data(tb1[NL80211_ATTR_STA_INFO]), + nla_len(tb1[NL80211_ATTR_STA_INFO]), NULL); + if (tb2[NL80211_STA_INFO_SIGNAL]) { + g_bss_info.rssi = + nla_get_u8(tb2[NL80211_STA_INFO_SIGNAL]); + g_bss_info.rssi -= 100; + } else { + wpa_printf(MSG_ERROR,"NL80211_STA_INFO_SIGNAL not found"); + } + g_bss_info.snr = g_bss_info.rssi - g_bss_info.noise; + + attr1 = tb2[NL80211_STA_INFO_TX_BITRATE]; + if (attr1) { + struct nlattr *tb3[NL80211_RATE_INFO_MAX + 1]; + + nla_parse(tb3, NL80211_RATE_INFO_MAX, + nla_data(attr1), nla_len(attr1), + NULL); + if (tb3[NL80211_RATE_INFO_BITRATE32]) { + g_bss_info.data_rate = nla_get_u32( + tb3[NL80211_RATE_INFO_BITRATE32])/10; + } else if (tb3[NL80211_RATE_INFO_BITRATE]) { + g_bss_info.data_rate = nla_get_u16( + tb3[NL80211_RATE_INFO_BITRATE])/10; + } + + } else { + wpa_printf(MSG_ERROR,"NL80211_STA_INFO_TX_BITRATE not found"); + } + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO not found"); + } + } else { + wpa_printf(MSG_ERROR, + "QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR not found"); + } + + if (tb_vendor[GET_STATION_INFO_AKM]) { + g_bss_info.akm = nla_get_u32( + tb_vendor[GET_STATION_INFO_AKM]); + } + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]) + g_bss_info.mode_80211 = nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]); + + attr = tb_vendor[GET_STATION_INFO_VHT_OPERATION]; + attr1 = tb_vendor[GET_STATION_INFO_HT_OPERATION]; + attr2 = tb_vendor[GET_STATION_INFO_HE_OPERATION]; + if (attr) { + struct ieee80211_vht_operation *info = nla_data(attr); + + switch (info->vht_op_info_chwidth) { + case CHANWIDTH_USE_HT: + if (attr1) { + struct ieee80211_ht_operation *info; + + info = nla_data(attr1); + g_bss_info.bw = info->ht_param ? 40:20; + } + break; + case CHANWIDTH_80MHZ: + seg1 = info->vht_op_info_chan_center_freq_seg1_idx; + if (seg1) + /* Notifying 80P80 also as bandwidth = 160 */ + g_bss_info.bw = 160; + else + g_bss_info.bw = 80; + break; + case CHANWIDTH_160MHZ: + g_bss_info.bw = 160; + break; + case CHANWIDTH_80P80MHZ: + g_bss_info.bw = 160; + break; + default: + wpa_printf(MSG_ERROR,"Invalid channel width received : %u", + info->vht_op_info_chwidth); + } + } else if (attr1) { + struct ieee80211_ht_operation *info = nla_data(attr1); + + g_bss_info.bw = info->ht_param ? 40:20; + } else + g_bss_info.bw = 20; + + if (attr2) { + struct ieee80211_he_operation *he_info = nla_data(attr2); + uint8_t *opr, ch_bw = CHANNEL_BW_INVALID; + + /* Check optional field in he_info is present of not */ + if (!he_info || (nla_len(attr2) <= + (sizeof(he_info->he_oper_params) + + sizeof(he_info->he_mcs_nss_set)))) { + he_info ? wpa_printf(MSG_ERROR,"Invalid he operation len: %d", nla_len(attr2)): + wpa_printf(MSG_ERROR,"Invalid he_info: NULL"); + goto parse_beacon_ies; + } + + opr = (uint8_t *)he_info; + /* Point to operational field */ + opr += (sizeof(he_info->he_oper_params) + + sizeof(he_info->he_mcs_nss_set)); + if (he_info->he_oper_params & + IEEE80211_HE_OPERATION_VHT_OPER_MASK) { + ch_bw = opr[HE_OPER_VHT_CH_WIDTH_OFFSET]; + switch (ch_bw) { + case CHANWIDTH_USE_HT: + /* TO DO */ + break; + case CHANWIDTH_80MHZ: + seg1 = opr[HE_OPER_VHT_CENTER_FRQ_SEG1_OFFSET]; + if (seg1) + /* Notifying 80P80 also as bandwidth = 160 */ + g_bss_info.bw = 160; + else + g_bss_info.bw = 80; + break; + case CHANWIDTH_160MHZ: + g_bss_info.bw = 160; + break; + case CHANWIDTH_80P80MHZ: + g_bss_info.bw = 160; + break; + default: + break; + } + opr += (HE_OPER_VHT_MAX_OFFSET + 1); + } + + if (he_info->he_oper_params & + IEEE80211_HE_OPERATION_CO_LOC_BSS_MASK) { + opr += (HE_OPER_CO_LOCATED_MAX_OFFSET + 1); + } + + if (he_info->he_oper_params & + IEEE80211_HE_OPERATION_6G_OPER_MASK) { + ch_bw = (opr[HE_OPER_6G_PARAMS_OFFSET] & + HE_OPER_6G_PARAMS_SUB_CH_BW_MASK); + switch (ch_bw) { + case HE_CHANWIDTH_20MHZ: + g_bss_info.bw = 20; + break; + case HE_CHANWIDTH_40MHZ: + g_bss_info.bw = 40; + break; + case HE_CHANWIDTH_80MHZ: + g_bss_info.bw = 80; + break; + case HE_CHANWIDTH_160MHZ: + /* Notifying 80P80 also as bandwidth = 160 */ + g_bss_info.bw = 160; + break; + default: + wpa_printf(MSG_ERROR,"Invalid channel width received : %u", ch_bw); + } + } + + } + +parse_beacon_ies: + attr = tb_vendor[GET_STATION_INFO_BEACON_IES]; + if (attr) { + beacon_ies = nla_data(attr); + + beacon_ies_len = nla_len(attr); + if (beacon_ies && beacon_ies_len > 12) { + beacon_ies += 12; + beacon_ies_len -= 12; + } + } + + if (tb_vendor[GET_STATION_INFO_DRIVER_DISCONNECT_REASON]) { + g_bss_info.disc_reasn_code = nla_get_u32(tb_vendor[ + GET_STATION_INFO_DRIVER_DISCONNECT_REASON]); + } + snprintf(info->reply_buf, info->reply_buf_len, + "%02x%02x%02x %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %u %s %d %d %d %d %d %d %d %d %d %d %d %d %d", + g_bss_info.oui[0], + g_bss_info.oui[1], + g_bss_info.oui[2], + g_bss_info.ssid, + g_bss_info.channel, + g_bss_info.bw, + g_bss_info.rssi, + g_bss_info.data_rate, + g_bss_info.mode_80211, + -1, + -1, + -1, + g_bss_info.snr, + g_bss_info.noise, + g_bss_info.akm, + g_bss_info.roaming_count, + -1, + -1, + -1, + -1, + g_bss_info.disc_reasn_code, + info->country, + g_bss_info.ani_level, + -1, + -1, + -1, + g_bss_info.roam_trigger_reason, + g_bss_info.roam_fail_reason, + g_bss_info.roam_invoke_fail_reason, + g_bss_info.tsf_out_of_sync_count, + g_bss_info.latest_tx_power, + g_bss_info.latest_tx_rate, + g_bss_info.target_power_24g_1mbps, + g_bss_info.target_power_24g_6mbps, + g_bss_info.target_power_5g_6mbps); + + return 0; +} + +static int parse_get_feature_info(struct resp_info *info, struct nlattr *vendata, + int datalen) +{ + struct nlattr *tb_vendor[NUM_QCA_WLAN_VENDOR_FEATURES + 1]; + struct nlattr *attr; + nla_parse(tb_vendor, NUM_QCA_WLAN_VENDOR_FEATURES, + vendata, datalen, NULL); + attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS]; + if (attr) { + snprintf(info->reply_buf, info->reply_buf_len, "%u", + nla_get_u32(attr)); + wpa_printf(MSG_DEBUG, "%s: driver supported feature info = %s", + __func__, info->reply_buf); + } else { + snprintf(info->reply_buf, info->reply_buf_len, "FAIL"); + return -1; + } + return 0; +} +static int handle_response(struct resp_info *info, struct nlattr *vendata, + int datalen) +{ + switch (info->subcmd) { + case QCA_NL80211_VENDOR_SUBCMD_GET_STATION: + os_memset(info->reply_buf, 0, info->reply_buf_len); + if (info->cmd_type == GETSTATSBSSINFO) + parse_station_info(info, vendata, datalen); + + wpa_printf(MSG_INFO,"STAINFO: %s", info->reply_buf); + break; + case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: + os_memset(info->reply_buf, 0, info->reply_buf_len); + parse_get_feature_info(info, vendata, datalen); + break; + default: + wpa_printf(MSG_ERROR,"Unsupported response type: %d", info->subcmd); + break; + } + return 0; +} + +static int response_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *mHeader; + struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1]; + struct nlattr *vendata; + int datalen; + struct resp_info *info = (struct resp_info *) arg; + int status; + + mHeader = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, + genlmsg_attrdata(mHeader, 0), + genlmsg_attrlen(mHeader, 0), NULL); + + if (mAttributes[NL80211_ATTR_VENDOR_DATA]) { + vendata = nla_data(mAttributes[NL80211_ATTR_VENDOR_DATA]); + datalen = nla_len(mAttributes[NL80211_ATTR_VENDOR_DATA]); + if (!vendata) { + wpa_printf(MSG_ERROR,"Vendor data not found"); + return -1; + } + status = handle_response(info, vendata, datalen); + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found"); + status = -1; + } + + return status; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *err = (int *)arg; + + *err = 0; + return NL_STOP; +} + +int wpa_driver_nl80211_oem_event(struct wpa_driver_nl80211_data *drv, + u32 vendor_id, u32 subcmd, + u8 *data, size_t len) +{ + int ret = -1, lib_n; + if (wpa_driver_oem_initialize(&oem_cb_table) != WPA_DRIVER_OEM_STATUS_FAILURE && + oem_cb_table) { + for (lib_n = 0; + oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL; + lib_n++) { + if(oem_cb_table[lib_n].wpa_driver_nl80211_driver_oem_event) { + ret = oem_cb_table[lib_n].wpa_driver_nl80211_driver_oem_event( + drv, vendor_id,subcmd, data, len); + if (ret == WPA_DRIVER_OEM_STATUS_SUCCESS ) { + break; + } else if (ret == WPA_DRIVER_OEM_STATUS_ENOSUPP) { + continue; + } else if (ret == WPA_DRIVER_OEM_STATUS_FAILURE) { + wpa_printf(MSG_DEBUG, "%s: Received error: %d", + __func__, ret); + break; + } + } + } + } + + return ret; +} + +static int wpa_driver_restart_csi(struct i802_bss *bss, int *status); + +int wpa_driver_nl80211_driver_event(struct wpa_driver_nl80211_data *drv, + u32 vendor_id, u32 subcmd, + u8 *data, size_t len) +{ + int ret = -1; + int status = -1; + struct i802_bss *bss; + + ret = wpa_driver_nl80211_oem_event(drv, vendor_id, subcmd, + data, len); + + if(ret != WPA_DRIVER_OEM_STATUS_ENOSUPP) + return ret; + + switch(subcmd) { + case QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: + ret = wpa_driver_twt_async_resp_event(drv, vendor_id, subcmd, + data, len); + break; + case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: + if(g_csi_param.current_state == CSI_STATE_START) { + bss = get_bss_ifindex(drv, drv->ifindex); + if(bss == NULL) { + wpa_printf(MSG_DEBUG, "%s: bss is NULL", + __func__); + break; + } + if(wpa_driver_restart_csi(bss, &status)) + wpa_printf(MSG_DEBUG, "csi_restart failed %d", + status); + } + break; + default: + break; + } + return ret; +} + +static int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = (int *)arg; + + *ret = 0; + return NL_SKIP; +} + + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = (int *)arg; + + *ret = err->error; + wpa_printf(MSG_ERROR,"%s received : %d - %s", __func__, + err->error, strerror(err->error)); + return NL_SKIP; +} + + +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} + +static int send_nlmsg(struct nl_sock *cmd_sock, struct nl_msg *nlmsg, + nl_recvmsg_msg_cb_t customer_cb, void *arg) +{ + int err = 0; + struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); + + if (!cb) + goto out; + + err = nl_send_auto_complete(cmd_sock, nlmsg); /* send message */ + if (err < 0) + goto out; + + err = 1; + + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + if (customer_cb) + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, customer_cb, arg); + + while (err > 0) { /* wait for reply */ + int res = nl_recvmsgs(cmd_sock, cb); + + if (res) + wpa_printf(MSG_ERROR,"nl80211: %s->nl_recvmsgs failed: %d", + __func__, res); + } +out: + nl_cb_put(cb); + if (nlmsg) + nlmsg_free(nlmsg); + return err; +} + +static int chartohex(char c) +{ + int val = -1; + + if (c >= '0' && c <= '9') + val = c - '0'; + else if (c >= 'a' && c <= 'f') + val = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + val = c - 'A' + 10; + + return val; +} + +static int convert_string_to_bytes(u8 *addr, const char *text, u16 max_bytes) +{ + u16 i = 0; + int nibble; + const char *temp = text; + + while (temp && *temp != '\0' && i < max_bytes) { + nibble = chartohex(*temp++); + if (nibble == -1) + return -1; + addr[i] = nibble << 4; + nibble = chartohex(*temp++); + if (nibble == -1) + return -1; + addr[i++] += nibble; + if (*temp == ':') + temp++; + } + + return i; +} + +/* + * Client can send the cell switch mode in below format + * + * SETCELLSWITCHMODE <cs mode> + * + * examples: + * For Default Mode - "SETCELLSWITCHMODE 0" + * To Disable Roaming - "SETCELLSWITCHMODE 1" + * For Partial Scan - "SETCELLSWITCHMODE 2" + */ +static int parse_and_populate_setcellswitchmode(struct nl_msg *nlmsg, + char *cmd) +{ + uint32_t all_trigger_bitmap, scan_scheme_bitmap; + uint32_t cellswm; + struct nlattr *config; + + cellswm = atoi(cmd); + if (cellswm < 0 || cellswm > 2) { + wpa_printf(MSG_ERROR,"Invalid cell switch mode: %d", cellswm); + return -1; + } + wpa_printf(MSG_DEBUG, "cell switch mode: %d", cellswm); + + all_trigger_bitmap = QCA_ROAM_TRIGGER_REASON_PER | + QCA_ROAM_TRIGGER_REASON_BEACON_MISS | + QCA_ROAM_TRIGGER_REASON_POOR_RSSI | + QCA_ROAM_TRIGGER_REASON_BETTER_RSSI | + QCA_ROAM_TRIGGER_REASON_PERIODIC | + QCA_ROAM_TRIGGER_REASON_DENSE | + QCA_ROAM_TRIGGER_REASON_BTM | + QCA_ROAM_TRIGGER_REASON_BSS_LOAD | + QCA_ROAM_TRIGGER_REASON_USER_TRIGGER | + QCA_ROAM_TRIGGER_REASON_DEAUTH | + QCA_ROAM_TRIGGER_REASON_IDLE | + QCA_ROAM_TRIGGER_REASON_TX_FAILURES | + QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN; + + scan_scheme_bitmap = QCA_ROAM_TRIGGER_REASON_PER | + QCA_ROAM_TRIGGER_REASON_BEACON_MISS | + QCA_ROAM_TRIGGER_REASON_POOR_RSSI | + QCA_ROAM_TRIGGER_REASON_BSS_LOAD | + QCA_ROAM_TRIGGER_REASON_BTM; + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET) || + nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID, 1)) { + wpa_printf(MSG_ERROR,"Failed to put: roam_subcmd/REQ_ID"); + } + + config = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL); + if (config == NULL) + goto fail; + + switch (cellswm){ + case 0: + if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, all_trigger_bitmap)) { + wpa_printf(MSG_ERROR,"Failed to set: ROAM_CONTROL_TRIGGERS"); + goto fail; + } + break; + case 1: + if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, 0)) { + wpa_printf(MSG_ERROR,"Failed to unset: ROAM_CONTROL_TRIGGERS"); + goto fail; + } + break; + case 2: + if (nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_TRIGGERS, all_trigger_bitmap) || + nla_put_u32(nlmsg, QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS, scan_scheme_bitmap)) { + wpa_printf(MSG_ERROR,"Failed to set: ROAM_CONTROL_TRIGGERS_SCAN_SCHEME"); + goto fail; + } + break; + } + nla_nest_end(nlmsg, config); + + return 0; +fail: + return -1; + +} + +static int populate_nlmsg(struct nl_msg *nlmsg, char *cmd, + enum get_info_cmd type) +{ + struct nlattr *attr; + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (attr == NULL) + return -1; + + switch (type) { + case GETSTATSBSSINFO: + if (nla_put_flag(nlmsg, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO)) { + wpa_printf(MSG_ERROR,"Failed to put flag QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO"); + return -1; + } + break; + case SETCELLSWITCHMODE: + if (parse_and_populate_setcellswitchmode(nlmsg, cmd) != 0) { + wpa_printf(MSG_ERROR, "Failed to populate nlmsg"); + return -1; + } + break; + default: + wpa_printf(MSG_ERROR,"Unsupported command: %d", type); + break; + } + + nla_nest_end(nlmsg, attr); + return 0; +} + +static char *skip_white_space(char *cmd) +{ + char *pos = cmd; + + while (*pos == ' ') + pos++; + + return pos; +} + +void ap_sta_copy_supp_op_classes(const u8 *supp_op_classes, + size_t supp_op_classes_len) { + if (!supp_op_classes) + return; + os_free(g_sta_info.supp_op_classes); + g_sta_info.supp_op_classes = malloc(1 + supp_op_classes_len); + if(!g_sta_info.supp_op_classes) + return; + g_sta_info.supp_op_classes[0] = supp_op_classes_len; + os_memcpy(g_sta_info.supp_op_classes + 1, supp_op_classes, + supp_op_classes_len); +} + +void ap_sta_copy_channels(const u8 *supp_channels, + size_t supp_channels_len) { + if (!supp_channels) + return; + os_free(g_sta_info.supp_channels); + g_sta_info.supp_channels = malloc(1 + supp_channels_len); + if(!g_sta_info.supp_channels) + return; + g_sta_info.supp_channels[0] = supp_channels_len; + os_memcpy(g_sta_info.supp_channels + 1, supp_channels, + supp_channels_len); +} + +static void parse_ext_ie(const u8 *ie, int ie_len) +{ + u8 ext_id; + + if (ie_len < 1) { + wpa_printf(MSG_ERROR,"parse error, ie_len = %d", ie_len); + return; + } + + ext_id = *ie++; + ie_len--; + + switch (ext_id) { + case WLAN_EID_EXT_HE_CAPABILITIES: + wpa_printf(MSG_INFO,"HE supported"); + g_sta_info.flags.he_supported = 1; + break; + default: + wpa_printf(MSG_DEBUG,"ext_id = %d", ext_id); + break; + } + + return; +} + +static void parse_assoc_req_ies(const u8 *ies, int ies_len) +{ + int left = ies_len; + const u8 *pos = ies; + + while (left >= 2) { + u8 id, ie_len; + id = *pos++; + ie_len = *pos++; + left -= 2; + + if (ie_len > left) { + wpa_printf(MSG_ERROR,"parse error, id = %d, ie_len = %d, left = %d", + id, ie_len, left); + return; + } + + switch (id) { + case WLAN_EID_SUPPORTED_OPERATING_CLASSES: + ap_sta_copy_supp_op_classes(pos, ie_len); + break; + case WLAN_EID_SUPPORTED_CHANNELS: + ap_sta_copy_channels(pos, ie_len); + break; + case WLAN_EID_HT_CAP: + wpa_printf(MSG_INFO,"HT supported"); + g_sta_info.flags.ht_supported = 1; + break; + case WLAN_EID_VHT_CAP: + wpa_printf(MSG_INFO,"VHT supported"); + g_sta_info.flags.vht_supported = 1; + break; + case WLAN_EID_EXTENSION: + parse_ext_ie(pos, ie_len); + break; + default: + break; + } + + left -= ie_len; + pos += ie_len; + } + + if (left) + wpa_printf(MSG_ERROR,"parse error, left = %d", left); +} + +void op_class_band_conversion(u8 *op_classes) { + int count = (g_sta_info.supp_op_classes[0]); + int i = 1; + int temp; + + if (count <= 1) + g_sta_info.supported_band = 0; + while((count-1) != 0) { + temp = g_sta_info.supp_op_classes[i]; + if (temp >= 81 && temp <= 84) + g_sta_info.supported_band |= BIT(0); + else if (temp >= 115 && temp <= 130) + g_sta_info.supported_band |= BIT(1); + else if (temp >= 131 && temp <= 135) + g_sta_info.supported_band |= BIT(2); + i++; + count--; + } +} + +void supp_channels_band_conversion(u8 *supp_channels) { + int count = 0; + int i = 1; + int temp = 0; + + count = (g_sta_info.supp_channels[0]); + if (count < 2) + g_sta_info.supported_band = 0; + + while((count-1) >= 0) { + temp = g_sta_info.supp_channels[i]; + if (temp >= 1 && temp <= 13) + g_sta_info.supported_band |= BIT(0); + else if (temp >= 32 && temp <= 173) + g_sta_info.supported_band |= BIT(1); + i += 2; + count -= 2; + } +} + +static int fill_sta_info(struct remote_sta_info *sta_info, + char *buf, size_t buf_len) +{ + int ret; + if (sta_info->num_sta == 1) { + if (sta_info->show_band) + ret = snprintf(buf, buf_len, + "%02x:%02x:%02x:%02x:%02x:%02x %d %d %04x %02x:%02x:%02x %d %d %d %d %d %d %d %d %d %s %d %d %d %d %d %d %d %d %d %d %d %d %d", + sta_info->mac_addr[0], sta_info->mac_addr[1], + sta_info->mac_addr[2], sta_info->mac_addr[3], + sta_info->mac_addr[4], sta_info->mac_addr[5], + sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts, + sta_info->cap, sta_info->mac_addr[0], + sta_info->mac_addr[1], sta_info->mac_addr[2], + sta_info->freq, + sta_info->bandwidth, + sta_info->rssi, + sta_info->data_rate, + sta_info->dot11_mode, + -1, + -1, + sta_info->reason, + sta_info->supported_mode, + sta_info->country, + sta_info->ani_level, + -1, + -1, + -1, + sta_info->roam_trigger_reason, + sta_info->roam_fail_reason, + sta_info->roam_invoke_fail_reason, + sta_info->tsf_out_of_sync_count, + sta_info->latest_tx_power, + sta_info->latest_tx_rate, + sta_info->target_power_24g_1mbps, + sta_info->target_power_24g_6mbps, + sta_info->target_power_5g_6mbps); + else + ret = snprintf(buf, buf_len, + "%02x:%02x:%02x:%02x:%02x:%02x %d %d %04x %02x:%02x:%02x %d %d %d %d %d %d %d %d %u %s %d %d %d %d %d %d %d %d %d %d %d %d %d", + sta_info->mac_addr[0], sta_info->mac_addr[1], + sta_info->mac_addr[2], sta_info->mac_addr[3], + sta_info->mac_addr[4], sta_info->mac_addr[5], + sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts, + sta_info->cap, sta_info->mac_addr[0], + sta_info->mac_addr[1], sta_info->mac_addr[2], + sta_info->freq, + sta_info->bandwidth, + sta_info->rssi, + sta_info->data_rate, + sta_info->supported_mode, + -1, + -1, + sta_info->reason, + sta_info->supported_band, + sta_info->country, + sta_info->ani_level, + -1, + -1, + -1, + sta_info->roam_trigger_reason, + sta_info->roam_fail_reason, + sta_info->roam_invoke_fail_reason, + sta_info->tsf_out_of_sync_count, + sta_info->latest_tx_power, + sta_info->latest_tx_rate, + sta_info->target_power_24g_1mbps, + sta_info->target_power_24g_6mbps, + sta_info->target_power_5g_6mbps); + } else { + ret = snprintf(buf, buf_len, + "%d %d %04x %d %d %d %d %d %d %d %d %d %s", + sta_info->rx_retry_pkts, sta_info->rx_bcmc_pkts, + -1, /* CAP */ + -1, /* Channel */ + -1, /* Bandwidth */ + -1, /* Rssi */ + -1, /* Data_rate */ + -1, /* 11_mode */ + -1, + -1, + -1, /* Reason */ + -1, /* Support_mode */ + sta_info->country); + } + return ret; +} + +static int get_sta_info_legacy_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *msg_hdr; + struct nlattr *tb[NL80211_ATTR_MAX_INTERNAL + 1]; + struct nlattr *tb_vendor[NL80211_ATTR_MAX_INTERNAL + 1]; + struct nlattr *vendor_data, *attr_link_info; + int vendor_len; + struct resp_info *info = (struct resp_info *)arg; + u8 *assoc_req_ie = NULL; + size_t assoc_req_ie_len = 0; + + if (!info) { + wpa_printf(MSG_ERROR,"Invalid arg"); + return -1; + } + + wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x", + info->mac_addr[0], info->mac_addr[1], info->mac_addr[2], + info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]); + + msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(tb, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(msg_hdr, 0), + genlmsg_attrlen(msg_hdr, 0), NULL); + + if (!tb[NL80211_ATTR_VENDOR_DATA]) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA parse error"); + return -1; + } + + vendor_data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]); + vendor_len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); + + if (nla_parse(tb_vendor, NL80211_ATTR_MAX_INTERNAL, + vendor_data, vendor_len, NULL)) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found"); + return -1; + } + + attr_link_info = tb_vendor[QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR]; + if (attr_link_info) { + struct nlattr *tb_link_info[NL80211_ATTR_MAX + 1]; + struct nlattr *attr_survey_info, *attr_sta_info; + + nla_parse(tb_link_info, NL80211_ATTR_MAX, nla_data(attr_link_info), + nla_len(attr_link_info), NULL); + attr_survey_info = tb_link_info[NL80211_ATTR_SURVEY_INFO]; + if (attr_survey_info) { + struct nlattr *tb_survey_info[NL80211_SURVEY_INFO_MAX + 1]; + + nla_parse(tb_survey_info, NL80211_SURVEY_INFO_MAX, + nla_data(attr_survey_info), + nla_len(attr_survey_info), NULL); + if (tb_survey_info[NL80211_SURVEY_INFO_FREQUENCY]) { + g_sta_info.freq = + nla_get_u32(tb_survey_info[NL80211_SURVEY_INFO_FREQUENCY]); + wpa_printf(MSG_INFO,"channel %d", g_sta_info.freq); + } + } + + attr_sta_info = tb_link_info[NL80211_ATTR_STA_INFO]; + if (attr_sta_info) { + struct nlattr *tb_sta_info[NL80211_STA_INFO_MAX + 1]; + + nla_parse(tb_sta_info, NL80211_STA_INFO_MAX, + nla_data(attr_sta_info), + nla_len(attr_sta_info), NULL); + if (tb_sta_info[NL80211_STA_INFO_SIGNAL]) { + g_sta_info.rssi = nla_get_u8(tb_sta_info[NL80211_STA_INFO_SIGNAL]); + g_sta_info.rssi -= NOISE_FLOOR_DBM; + wpa_printf(MSG_INFO,"rssi %d", g_sta_info.rssi); + } + if (tb_sta_info[NL80211_STA_INFO_TX_BITRATE]) { + struct nlattr *tb_antenna_info[NL80211_RATE_INFO_MAX + 1]; + nla_parse(tb_antenna_info, NL80211_RATE_INFO_MAX, + nla_data(tb_sta_info[NL80211_STA_INFO_TX_BITRATE]), + nla_len(tb_sta_info[NL80211_STA_INFO_TX_BITRATE]), + NULL); + } + } + + if (tb_link_info[NL80211_ATTR_REASON_CODE]) { + g_sta_info.reason = + nla_get_u32(tb_link_info[NL80211_ATTR_REASON_CODE]); + wpa_printf(MSG_INFO,"reason %d", g_sta_info.reason); + } + + if (tb_link_info[NL80211_ATTR_STA_CAPABILITY]) { + g_sta_info.cap = + nla_get_u16(tb_link_info[NL80211_ATTR_STA_CAPABILITY]); + wpa_printf(MSG_INFO,"cap %04x", g_sta_info.cap); + } + } + + if (tb_vendor[GET_STATION_INFO_REMOTE_LAST_RX_RATE]) { + g_sta_info.data_rate = + nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_LAST_RX_RATE]); + wpa_printf(MSG_INFO,"data_rate %d", g_sta_info.data_rate); + } + + if (tb_vendor[GET_STATION_INFO_REMOTE_RX_RETRY_COUNT]) { + g_sta_info.rx_retry_pkts += + nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_RX_RETRY_COUNT]); + wpa_printf(MSG_INFO,"rx_retry_pkts %d", g_sta_info.rx_retry_pkts); + } + + if (tb_vendor[GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT]) { + g_sta_info.rx_bcmc_pkts += + nla_get_u32(tb_vendor[GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT]); + wpa_printf(MSG_INFO,"rx_bcmc_pkts %d", g_sta_info.rx_bcmc_pkts); + } + + if (tb_vendor[GET_STATION_INFO_REMOTE_CH_WIDTH]) { + g_sta_info.bandwidth = + nla_get_u8(tb_vendor[GET_STATION_INFO_REMOTE_CH_WIDTH]); + wpa_printf(MSG_INFO,"bandwidth %d", g_sta_info.bandwidth); + } + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]) { + g_sta_info.dot11_mode = + nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_802_11_MODE]); + wpa_printf(MSG_INFO,"dot11_mode %d", g_sta_info.dot11_mode); + } + + if (tb_vendor[GET_STATION_INFO_REMOTE_SUPPORTED_MODE]) { + g_sta_info.supported_mode = + nla_get_u8(tb_vendor[GET_STATION_INFO_REMOTE_SUPPORTED_MODE]); + wpa_printf(MSG_INFO,"supported_mode %d", g_sta_info.supported_mode); + } + + if (tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]) { + assoc_req_ie = + nla_data(tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]); + assoc_req_ie_len = + nla_len(tb_vendor[GET_STATION_INFO_ASSOC_REQ_IES]); + } + + parse_assoc_req_ies(assoc_req_ie, assoc_req_ie_len); + + if (g_sta_info.supp_op_classes) { + op_class_band_conversion(g_sta_info.supp_op_classes); + g_sta_info.show_band = true; + } + else if (g_sta_info.supp_channels) { + supp_channels_band_conversion(g_sta_info.supp_channels); + g_sta_info.show_band = true; + } + else + wpa_printf(MSG_ERROR,"supp_op_classes and supp_channels both are null"); + + g_sta_info.num_received_vendor_sta_info++; + + wpa_printf(MSG_INFO,"num_received_vendor_sta_info %d", + g_sta_info.num_received_vendor_sta_info); + + return 0; +} + +static int +wpa_driver_send_get_sta_info_legacy_cmd(struct i802_bss *bss, u8 *mac, + int *status) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct nlattr *attr; + struct resp_info info; + + memset(&info, 0, sizeof(info)); + os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN); + os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN); + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_GET_STATION); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!attr) { + nlmsg_free(nlmsg); + return -1; + } + + if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE, + MAC_ADDR_LEN, mac)) { + wpa_printf(MSG_ERROR,"Failed to put QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE"); + nlmsg_free(nlmsg); + return -1; + } + + nla_nest_end(nlmsg, attr); + + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + get_sta_info_legacy_handler, &info); + if (*status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", *status); + return -1; + } + + return 0; +} + +static int get_sta_info_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *msg_hdr; + struct nlattr *tb[NL80211_ATTR_MAX_INTERNAL + 1]; + struct nlattr *tb_vendor[GET_STA_INFO_MAX + 1]; + struct nlattr *vendor_data; + int vendor_len; + struct resp_info *info = (struct resp_info *)arg; + uint8_t mac_addr[MAC_ADDR_LEN]; + + if (!info) { + wpa_printf(MSG_ERROR,"Invalid arg"); + return -1; + } + + msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(tb, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(msg_hdr, 0), + genlmsg_attrlen(msg_hdr, 0), NULL); + + if (!tb[NL80211_ATTR_VENDOR_DATA]) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found"); + return -1; + } + + vendor_data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]); + vendor_len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]); + + if (nla_parse(tb_vendor, GET_STA_INFO_MAX, + vendor_data, vendor_len, NULL)) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA parse error"); + return -1; + } + + if (tb_vendor[GET_STA_INFO_MAC]) { + nla_memcpy(mac_addr, + tb_vendor[GET_STA_INFO_MAC],MAC_ADDR_LEN); + if (os_memcmp(mac_addr, info->mac_addr, MAC_ADDR_LEN)) { + wpa_printf(MSG_ERROR,"MAC address mismatch"); + return -1; + } + } + + wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x", + info->mac_addr[0], info->mac_addr[1], info->mac_addr[2], + info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]); + + if (tb_vendor[GET_STA_INFO_RX_RETRY_COUNT]) { + g_sta_info.rx_retry_pkts += + nla_get_u32(tb_vendor[GET_STA_INFO_RX_RETRY_COUNT]); + wpa_printf(MSG_INFO,"rx_retry_pkts %d", g_sta_info.rx_retry_pkts); + } + + if (tb_vendor[GET_STA_INFO_RX_BC_MC_COUNT]) { + g_sta_info.rx_bcmc_pkts += + nla_get_u32(tb_vendor[GET_STA_INFO_RX_BC_MC_COUNT]); + wpa_printf(MSG_INFO,"rx_bcmc_pkts %d", g_sta_info.rx_bcmc_pkts); + } + + if (tb_vendor[GET_STA_INFO_TX_RETRY_SUCCEED]) { + g_sta_info.tx_pkts_retried += + nla_get_u32(tb_vendor[GET_STA_INFO_TX_RETRY_SUCCEED]); + wpa_printf(MSG_INFO,"tx_pkts_retried %d", g_sta_info.tx_pkts_retried); + } + + if (tb_vendor[GET_STA_INFO_TX_RETRY_EXHAUSTED]) { + g_sta_info.tx_pkts_retry_exhausted += + nla_get_u32(tb_vendor[GET_STA_INFO_TX_RETRY_EXHAUSTED]); + wpa_printf(MSG_INFO,"tx_pkts_retry_exhausted %d", g_sta_info.tx_pkts_retry_exhausted); + } + + if (tb_vendor[GET_STA_INFO_TARGET_TX_TOTAL]) { + g_sta_info.tx_pkts_fw_total += + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_TOTAL]); + wpa_printf(MSG_INFO,"tx_pkts_fw_total %d", g_sta_info.tx_pkts_fw_total); + } + + if (tb_vendor[GET_STA_INFO_TARGET_TX_RETRY]) { + g_sta_info.tx_pkts_fw_retries += + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_RETRY]); + wpa_printf(MSG_INFO,"tx_pkts_fw_retries %d", g_sta_info.tx_pkts_fw_retries); + } + + if (tb_vendor[GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED]) { + g_sta_info.tx_pkts_fw_retry_exhausted += + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED]); + wpa_printf(MSG_INFO,"tx_pkts_fw_retry_exhausted %d", g_sta_info.tx_pkts_fw_retry_exhausted); + } + + if (tb_vendor[GET_STA_INFO_ANI_LEVEL]) { + g_sta_info.ani_level = + nla_get_u32(tb_vendor[GET_STA_INFO_ANI_LEVEL]); + wpa_printf(MSG_INFO,"ani_level %d", g_sta_info.ani_level); + } + + if (tb_vendor[GET_STA_INFO_ROAM_TRIGGER_REASON]) { + g_sta_info.roam_trigger_reason = + nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_TRIGGER_REASON]); + wpa_printf(MSG_INFO,"roam_trigger_reason %d", g_sta_info.roam_trigger_reason); + } + + if (tb_vendor[GET_STA_INFO_ROAM_FAIL_REASON]) { + g_sta_info.roam_fail_reason = + nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_FAIL_REASON]); + wpa_printf(MSG_INFO,"roam_fail_reason %d", g_sta_info.roam_fail_reason); + } + + if (tb_vendor[GET_STA_INFO_ROAM_INVOKE_FAIL_REASON]) { + g_sta_info.roam_invoke_fail_reason = + nla_get_u32(tb_vendor[GET_STA_INFO_ROAM_INVOKE_FAIL_REASON]); + wpa_printf(MSG_INFO,"roam_invoke_fail_reason %d", g_sta_info.roam_invoke_fail_reason); + } + + if (tb_vendor[GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT]) { + g_sta_info.tsf_out_of_sync_count = + nla_get_u32(tb_vendor[GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT]); + wpa_printf(MSG_INFO,"tsf_out_of_sync_count %d", g_sta_info.tsf_out_of_sync_count); + } + + if (tb_vendor[GET_STA_INFO_LATEST_TX_POWER]) { + g_sta_info.latest_tx_power = + nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_TX_POWER]); + wpa_printf(MSG_INFO,"latest_tx_power %d", g_sta_info.latest_tx_power); + } + + if (tb_vendor[GET_STA_INFO_LATEST_TX_RATE]) { + g_sta_info.latest_tx_rate = + nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_TX_RATE]); + wpa_printf(MSG_INFO,"latest_tx_rate %d", g_sta_info.latest_tx_rate); + } + + if (tb_vendor[GET_STA_INFO_TARGET_POWER_24G_1MBPS]) { + g_sta_info.target_power_24g_1mbps = + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_24G_1MBPS]); + wpa_printf(MSG_INFO,"target_power_24g_1mbps %d", g_sta_info.target_power_24g_1mbps); + } + + if (tb_vendor[GET_STA_INFO_TARGET_POWER_24G_6MBPS]) { + g_sta_info.target_power_24g_6mbps = + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_24G_6MBPS]); + wpa_printf(MSG_INFO,"target_power_24g_6mbps %d", g_sta_info.target_power_24g_6mbps); + } + + if (tb_vendor[GET_STA_INFO_TARGET_POWER_5G_6MBPS]) { + g_sta_info.target_power_5g_6mbps = + nla_get_u32(tb_vendor[GET_STA_INFO_TARGET_POWER_5G_6MBPS]); + wpa_printf(MSG_INFO,"target_power_5g_6mbps %d", g_sta_info.target_power_5g_6mbps); + } + + if (tb_vendor[GET_STA_INFO_LATEST_RIX]) { + g_sta_info.latest_rix = + nla_get_u32(tb_vendor[GET_STA_INFO_LATEST_RIX]); + wpa_printf(MSG_INFO,"latest_rix %d", g_sta_info.latest_rix); + } + + + g_sta_info.num_received_vendor_sta_info++; + + wpa_printf(MSG_INFO,"num_received_vendor_sta_info %d", + g_sta_info.num_received_vendor_sta_info); + + return 0; +} + +static int wpa_driver_ioctl(struct i802_bss *bss, char *cmd, + char *buf, size_t buf_len, int *status, + struct wpa_driver_nl80211_data *drv) { + struct ifreq ifr; + android_wifi_priv_cmd priv_cmd; + memset(&ifr, 0, sizeof(ifr)); + memset(&priv_cmd, 0, sizeof(priv_cmd)); + os_memcpy(buf, cmd, strlen(cmd) + 1); + os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ); + priv_cmd.buf = buf; + priv_cmd.used_len = buf_len; + priv_cmd.total_len = buf_len; + ifr.ifr_data = &priv_cmd; + + if ((ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) { + wpa_printf(MSG_ERROR,"%s: failed to issue private commands\n", __func__); + *status = 1; + return WPA_DRIVER_OEM_STATUS_FAILURE; + } else { + wpa_printf(MSG_ERROR,"Response: %s", buf); + return WPA_DRIVER_OEM_STATUS_SUCCESS; + } +} + +static int wpa_driver_send_get_sta_info_cmd(struct i802_bss *bss, u8 *mac, + int *status, bool *new_cmd) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct nlattr *attr; + struct resp_info info; + + memset(&info, 0, sizeof(info)); + os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN); + os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN); + + *new_cmd = true; + + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!attr) { + nlmsg_free(nlmsg); + return -1; + } + + if (nla_put(nlmsg, GET_STA_INFO_MAC, + MAC_ADDR_LEN, mac)) { + wpa_printf(MSG_ERROR,"Failed to put GET_STA_INFO_MAC"); + nlmsg_free(nlmsg); + return -1; + } + + nla_nest_end(nlmsg, attr); + + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + get_sta_info_handler, &info); + if (*status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d, retrying with legacy command", *status); + *new_cmd = false; + return wpa_driver_send_get_sta_info_legacy_cmd(bss,mac,status); + } + + g_sta_info.num_request_vendor_sta_info++; + wpa_printf(MSG_INFO,"num_request_vendor_sta_info %d", + g_sta_info.num_request_vendor_sta_info); + + return 0; +} + +static int get_station_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *msg_hdr; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct nlattr *tb_sinfo[NL80211_STA_INFO_MAX + 1]; + struct nlattr *tb_rate[NL80211_RATE_INFO_MAX + 1]; + struct nlattr *sinfo_data, *attr; + int sinfo_len, tmp, num_chain = 0; + struct resp_info *info = (struct resp_info *)arg; + uint8_t mac_addr[MAC_ADDR_LEN]; + + if (!info) { + wpa_printf(MSG_ERROR,"Invalid arg"); + return -1; + } + + msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(msg_hdr, 0), + genlmsg_attrlen(msg_hdr, 0), NULL); + + if (tb[NL80211_ATTR_MAC]) { + nla_memcpy(mac_addr, tb[NL80211_ATTR_MAC], MAC_ADDR_LEN); + if (os_memcmp(mac_addr, info->mac_addr, MAC_ADDR_LEN)) { + wpa_printf(MSG_ERROR,"MAC address mismatch"); + return -1; + } + } + + wpa_printf(MSG_INFO,"Recv STA info %02x:%02x:%02x:%02x:%02x:%02x", + info->mac_addr[0], info->mac_addr[1], info->mac_addr[2], + info->mac_addr[3], info->mac_addr[4], info->mac_addr[5]); + + if (!tb[NL80211_ATTR_STA_INFO]) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO not found"); + return -1; + } + + sinfo_data = nla_data(tb[NL80211_ATTR_STA_INFO]); + sinfo_len = nla_len(tb[NL80211_ATTR_STA_INFO]); + + if (nla_parse(tb_sinfo, NL80211_STA_INFO_MAX, sinfo_data, sinfo_len, + NULL)) { + wpa_printf(MSG_ERROR,"NL80211_ATTR_STA_INFO parse error"); + return -1; + } + + /* No need to read for summary */ + if (g_sta_info.num_sta == 1) { + if (tb[NL80211_ATTR_IE]) + parse_assoc_req_ies(nla_data(tb[NL80211_ATTR_IE]), + nla_len(tb[NL80211_ATTR_IE])); + + attr = tb_sinfo[NL80211_STA_INFO_TX_BITRATE]; + if (attr) { + nla_parse(tb_rate, NL80211_RATE_INFO_MAX, + nla_data(attr), nla_len(attr), NULL); + + if (tb_rate[NL80211_RATE_INFO_BITRATE32]) { + g_sta_info.tx_rate = + nla_get_u32(tb_rate[NL80211_RATE_INFO_BITRATE32]); + wpa_printf(MSG_INFO,"tx_rate %d", g_sta_info.tx_rate); + } + + if (tb_rate[NL80211_RATE_INFO_160_MHZ_WIDTH]) + g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_160; + else if (tb_rate[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) + g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_80_80; + else if (tb_rate[NL80211_RATE_INFO_80_MHZ_WIDTH]) + g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_80; + else if (tb_rate[NL80211_RATE_INFO_40_MHZ_WIDTH]) + g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_40; + else + g_sta_info.bandwidth = QCA_VENDOR_WLAN_CHAN_WIDTH_20; + wpa_printf(MSG_INFO,"bandwidth %d", g_sta_info.bandwidth); + } + + attr = tb_sinfo[NL80211_STA_INFO_RX_BITRATE]; + if (attr) { + nla_parse(tb_rate, NL80211_RATE_INFO_MAX, + nla_data(attr), nla_len(attr), NULL); + if (tb_rate[NL80211_RATE_INFO_BITRATE32]) { + g_sta_info.data_rate = + nla_get_u32(tb_rate[NL80211_RATE_INFO_BITRATE32]); + wpa_printf(MSG_INFO,"data_rate %d", g_sta_info.data_rate); + } + } + + if (tb_sinfo[NL80211_STA_INFO_SIGNAL_AVG]) { + g_sta_info.rssi = + nla_get_u8(tb_sinfo[NL80211_STA_INFO_SIGNAL_AVG]); + g_sta_info.rssi -= NOISE_FLOOR_DBM; + wpa_printf(MSG_INFO,"rssi %d", g_sta_info.rssi); + } + + if (tb_sinfo[NL80211_STA_INFO_SIGNAL]) { + g_sta_info.rx_lastpkt_rssi = + nla_get_u8(tb_sinfo[NL80211_STA_INFO_SIGNAL]); + g_sta_info.rx_lastpkt_rssi -= NOISE_FLOOR_DBM; + wpa_printf(MSG_INFO,"rx_lastpkt_rssi %d", g_sta_info.rx_lastpkt_rssi); + } + + if (tb_sinfo[NL80211_STA_INFO_CHAIN_SIGNAL_AVG]) { + nla_for_each_nested(attr, + tb_sinfo[NL80211_STA_INFO_CHAIN_SIGNAL_AVG], + tmp) { + if (num_chain >= WMI_MAX_CHAINS) { + wpa_printf(MSG_ERROR,"WMI_MAX_CHAINS reached"); + break; + } + g_sta_info.avg_rssi_per_chain[num_chain] = nla_get_u8(attr); + g_sta_info.avg_rssi_per_chain[num_chain] -= NOISE_FLOOR_DBM; + wpa_printf(MSG_INFO,"avg_rssi_per_chain[%d] %d", num_chain, + g_sta_info.avg_rssi_per_chain[num_chain]); + num_chain++; + } + } + } + + if (tb_sinfo[NL80211_STA_INFO_TX_PACKETS]) { + g_sta_info.tx_pkts_total += + nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_PACKETS]); + g_sta_info.tx_pckts += + nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_PACKETS]); + wpa_printf(MSG_INFO,"tx_pkts_total %d", g_sta_info.tx_pkts_total); + wpa_printf(MSG_INFO,"tx_pckts %d", g_sta_info.tx_pckts); + } + + if (tb_sinfo[NL80211_STA_INFO_TX_FAILED]) { + g_sta_info.tx_failures += + nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_FAILED]); + wpa_printf(MSG_INFO,"tx_failures %d", g_sta_info.tx_failures); + } + + if (tb_sinfo[NL80211_STA_INFO_TX_RETRIES]) { + g_sta_info.tx_pkts_retries += + nla_get_u32(tb_sinfo[NL80211_STA_INFO_TX_RETRIES]); + wpa_printf(MSG_INFO,"tx_pkts_retries %d", g_sta_info.tx_pkts_retries); + } + + + g_sta_info.num_received_nl80211_sta_info++; + + wpa_printf(MSG_INFO,"num_received_nl80211_sta_info %d", + g_sta_info.num_received_nl80211_sta_info); + + return 0; +} + +static int wpa_driver_send_get_station_cmd(struct i802_bss *bss, u8 *mac, + int *status) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct resp_info info; + + memset(&info, 0, sizeof(info)); + os_memcpy(&info.mac_addr[0], mac, MAC_ADDR_LEN); + os_memcpy(&g_sta_info.mac_addr[0], mac, MAC_ADDR_LEN); + + nlmsg = prepare_nlmsg(drv, bss->ifname, NL80211_CMD_GET_STATION, 0, 0); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + if (nla_put(nlmsg, NL80211_ATTR_MAC, MAC_ADDR_LEN, mac)) { + wpa_printf(MSG_ERROR,"Failed to put NL80211_ATTR_MAC"); + nlmsg_free(nlmsg); + return -1; + } + + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + get_station_handler, &info); + if (*status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", *status); + return -1; + } + + g_sta_info.num_request_nl80211_sta_info++; + wpa_printf(MSG_INFO,"num_request_nl80211_sta_info %d", + g_sta_info.num_request_nl80211_sta_info); + + return 0; +} + +static int wpa_driver_get_sta_info(struct i802_bss *bss, u8 *mac, + int *status) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct hostapd_data *hapd = bss->ctx; + struct sta_info *iter, *sta = NULL; + bool new_cmd; + int ret; + char buf[MAX_DRV_CMD_SIZE]; + char *p; + + memset(buf, 0, sizeof(buf)); + + ret = wpa_driver_send_get_sta_info_cmd(bss, mac, status, &new_cmd); + if (ret < 0) + return ret; + + if (new_cmd) { + ret = wpa_driver_send_get_station_cmd(bss, mac, status); + if (ret < 0) + return ret; + + /* No need to read for summary */ + if (g_sta_info.num_sta == 1) { + if (!hapd) { + wpa_printf(MSG_ERROR,"hapd is NULL"); + return -1; + } + iter = hapd->sta_list; + while (iter) { + if (os_memcmp(mac, iter->addr, MAC_ADDR_LEN) == 0) { + sta = iter; + break; + } + iter = iter->next; + } + if (!sta) { + wpa_printf(MSG_ERROR,"STA is not found"); + return -1; + } + + g_sta_info.cap = sta->capability; + wpa_printf(MSG_INFO,"cap %04x", g_sta_info.cap); + g_sta_info.freq = (u32)hapd->iface->freq; + wpa_printf(MSG_INFO,"freq %d", g_sta_info.freq); + + if (g_sta_info.flags.he_supported) { + g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_AX; + g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_HE; + } else if (g_sta_info.flags.vht_supported) { + g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_AC; + g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_VHT; + } else if (g_sta_info.flags.ht_supported) { + g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_N; + g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_HT; + } else { + if (g_sta_info.freq < 4900) { + if (hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211B) + g_sta_info.dot11_mode = + QCA_VENDOR_WLAN_802_11_MODE_B; + else + g_sta_info.dot11_mode = + QCA_VENDOR_WLAN_802_11_MODE_G; + } else { + g_sta_info.dot11_mode = QCA_VENDOR_WLAN_802_11_MODE_A; + } + g_sta_info.supported_mode = QCA_VENDOR_WLAN_PHY_MODE_LEGACY; + } + + wpa_printf(MSG_INFO,"dot11_mode %d", g_sta_info.dot11_mode); + wpa_printf(MSG_INFO,"supported_mode %d", g_sta_info.supported_mode); + } + } + + if(wpa_driver_ioctl(bss, "GETCOUNTRYREV", buf, sizeof(buf), &status, drv) == 0){ + p = strstr(buf, " "); + if(p != NULL) + memcpy(g_sta_info.country, (p+1), strlen(p+1)+1);//length of p including null + }else{ + } + + wpa_printf(MSG_INFO,"STA information completed"); + + return 0; +} + +static int wpa_driver_get_all_sta_info(struct i802_bss *bss, int *status) +{ + struct hostapd_data *hapd = bss->ctx; + struct sta_info *sta; + int ret, total_ret = 0; + + if(bss->drv && bss->drv->nlmode != NL80211_IFTYPE_AP) { + wpa_printf(MSG_ERROR,"Not a hapd interface"); + return -1; + } + + if (!hapd) { + wpa_printf(MSG_ERROR,"hapd is NULL"); + return -1; + } + + g_sta_info.num_sta = hapd->num_sta; + + sta = hapd->sta_list; + while (sta) { + ret = wpa_driver_get_sta_info(bss, sta->addr, status); + if (ret < 0) + return ret; + sta = sta->next; + total_ret += ret; + } + + wpa_printf(MSG_INFO,"All STAs information completed"); + + return total_ret; +} + +static int wpa_driver_handle_get_sta_info(struct i802_bss *bss, char *cmd, + char *buf, size_t buf_len, + int *status) +{ + u8 mac[MAC_ADDR_LEN]; + int ret; + + os_memset(&g_sta_info, 0, sizeof(g_sta_info)); + + cmd = skip_white_space(cmd); + if (strlen(cmd) >= MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1 + && convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) > 0) { + g_sta_info.num_sta = 1; + ret = wpa_driver_get_sta_info(bss, mac, status); + if (ret < 0) + return ret; + } else { + ret = wpa_driver_get_all_sta_info(bss, status); + if (ret < 0) + return ret; + } + + if (ret == 0) { + ret = fill_sta_info(&g_sta_info, buf, buf_len); + wpa_printf(MSG_INFO,"%s", buf); + } else { + wpa_printf(MSG_ERROR,"Failed to get STA info, num_sta %d vendor_sent %d vendor_recv %d nl80211_send %d nl80211 recv %d", + g_sta_info.num_sta, + g_sta_info.num_request_vendor_sta_info, + g_sta_info.num_received_vendor_sta_info, + g_sta_info.num_request_nl80211_sta_info, + g_sta_info.num_received_nl80211_sta_info); + wpa_printf(MSG_ERROR,"GETSTAINFO failed"); + } + + return ret; +} + +static int thermal_info_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + int *param = arg; + struct nlattr *nl_vendor; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + nl_vendor = tb[NL80211_ATTR_VENDOR_DATA]; + if (!nl_vendor || nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX, + nla_data(nl_vendor), nla_len(nl_vendor), NULL)) { + wpa_printf(MSG_ERROR, "%s: No vendor data found", __func__); + return NL_SKIP; + } + + if (tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA]) + *param = (int) nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA]); + else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]) + *param = (int) nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL]); + else + wpa_printf(MSG_ERROR, "%s: failed to parse data", __func__); + + return NL_SKIP; +} + +static int wpa_driver_cmd_get_thermal_info(struct i802_bss *bss, int *result, int attr) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg = NULL; + struct nlattr *params = NULL; + int ret = 0; + + if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD) || + !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) || + nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE, attr)) { + nlmsg_free(msg); + return -1; + } + + nla_nest_end(msg, params); + ret = send_and_recv_msgs(drv, msg, thermal_info_handler, result, NULL, NULL); + if (!ret) + return 0; + wpa_printf(MSG_ERROR, "%s: Failed get thermal info, ret=%d(%s)", + __func__, ret, strerror(-ret)); + return ret; +} + +static int get_scan_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *msg_hdr; + struct nlattr *attr[NL80211_ATTR_MAX + 1]; + struct resp_info *info = (struct resp_info *)arg; + struct nlattr *bss_attr[NL80211_BSS_MAX + 1]; + char *bssid; + static struct nla_policy get_scan_policy[NL80211_BSS_MAX + 1] = { + [NL80211_BSS_BSSID] = {}, + [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_BSS_STATUS] = { .type = NLA_U32 }, + [NL80211_BSS_CHAN_WIDTH] = { .type = NLA_U32 }, + }; + + if (!info) { + wpa_printf(MSG_DEBUG, "resp_info is NULL"); + return NL_SKIP; + } + + msg_hdr = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(msg_hdr, 0), + genlmsg_attrlen(msg_hdr, 0), NULL); + + if (!attr[NL80211_ATTR_BSS]) { + wpa_printf(MSG_DEBUG, "no bss info"); + return NL_SKIP; + } + + if (nla_parse_nested(bss_attr, NL80211_BSS_MAX, + attr[NL80211_ATTR_BSS], + get_scan_policy)) { + wpa_printf(MSG_DEBUG, "parse bss attr fail"); + return NL_SKIP; + } + + if (!bss_attr[NL80211_BSS_BSSID]) + return NL_SKIP; + + if (!bss_attr[NL80211_BSS_STATUS]) + return NL_SKIP; + + if (nla_get_u32(bss_attr[NL80211_BSS_STATUS]) != + NL80211_BSS_STATUS_ASSOCIATED) + return NL_SKIP; + + bssid = nla_data(bss_attr[NL80211_BSS_BSSID]); + os_memcpy(g_csi_param.connected_bssid, bssid, MAC_ADDR_LEN); + + wpa_printf(MSG_DEBUG, "get connected bss"); + if (bss_attr[NL80211_BSS_FREQUENCY]) + wpa_printf(MSG_DEBUG, "freq %d", nla_get_u32(bss_attr[NL80211_BSS_FREQUENCY])); + + if (bss_attr[NL80211_BSS_CHAN_WIDTH]) + wpa_printf(MSG_DEBUG, "BW %d", nla_get_u32(bss_attr[NL80211_BSS_CHAN_WIDTH])); + + return 0; +} + +static int wpa_driver_send_get_scan_cmd(struct i802_bss *bss, int *status) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct resp_info info; + + os_memset(g_csi_param.connected_bssid, 0xff, MAC_ADDR_LEN); + nlmsg = prepare_nlmsg(drv, bss->ifname, NL80211_CMD_GET_SCAN, 0, NLM_F_DUMP); + if (!nlmsg) { + wpa_printf(MSG_ERROR, "Failed to allocate nl message"); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + get_scan_handler, &info); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} + +static int wpa_driver_start_csi_capture(struct i802_bss *bss, int *status, + int transport_mode) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct nlattr *attr, *attr_table, *attr_entry; + char ta_mask[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG); + if (!nlmsg) { + wpa_printf(MSG_ERROR, "Failed to allocate nl message"); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!attr) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION, + ENHANCED_CFR_VER)) { + wpa_printf(MSG_ERROR, "Failed to csi version"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE, + transport_mode)) { + wpa_printf(MSG_ERROR, "Failed to set transport mode"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_flag(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE)) { + wpa_printf(MSG_ERROR, "Failed to csi enable flag"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP, + CSI_GROUP_BITMAP)) { + wpa_printf(MSG_ERROR, "Failed to csi group bitmap"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE, + QCA_WLAN_VENDOR_CFR_TA_RA)) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + attr_table = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE); + if (!attr_table) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + attr_entry = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY); + if (!attr_entry) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER, + CSI_DEFAULT_GROUP_ID)) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER, + CSI_MGMT_BEACON)) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA, + MAC_ADDR_LEN, g_csi_param.connected_bssid)) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK, + MAC_ADDR_LEN, ta_mask)) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + nla_nest_end(nlmsg, attr_entry); + nla_nest_end(nlmsg, attr_table); + nla_nest_end(nlmsg, attr); + + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + g_csi_param.current_state = CSI_STATE_START; + + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} + +static int wpa_driver_stop_csi_capture(struct i802_bss *bss, int *status) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *nlmsg; + struct nlattr *attr; + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG); + if (!nlmsg) { + wpa_printf(MSG_ERROR, "Failed to allocate nl message"); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!attr) { + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION, + ENHANCED_CFR_VER)) { + wpa_printf(MSG_ERROR, "Failed to csi version"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + wpa_printf(MSG_DEBUG, "send stop csi cmd"); + nla_nest_end(nlmsg, attr); + *status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nl message with err %d", *status); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + g_csi_param.current_state = CSI_STATE_STOP; + + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} + +static void stop_csi_callback(int nsec) +{ + int status = 0; + + wpa_printf(MSG_DEBUG, "enter %s, nsec %d", __func__, nsec); + + wpa_driver_stop_csi_capture(g_csi_param.bss, &status); + if (status) + wpa_printf(MSG_ERROR, "Stop CSI failed"); +} + +static int wpa_driver_handle_csi_cmd(struct i802_bss *bss, char *cmd, + char *buf, size_t buf_len, + int *status) +{ + int csi_duration = -1; + int transport_mode = -1; + char *next_arg; + + cmd = skip_white_space(cmd); + wpa_printf(MSG_DEBUG, "cmd:%s", cmd); + if (os_strncasecmp(cmd, "start", 5) == 0) { + next_arg = get_next_arg(cmd); + csi_duration = atoi(next_arg); + + if (csi_duration < 0) { + wpa_printf(MSG_ERROR, "Invalid duration"); + snprintf(buf, buf_len, "FAIL, Invalid duration"); + *status = CSI_STATUS_REJECTED; + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + wpa_driver_send_get_scan_cmd(bss, status); + if (g_csi_param.connected_bssid[0] == 0xff) { + wpa_printf(MSG_DEBUG, "Not connected"); + snprintf(buf, buf_len, "FAIL, Not connected"); + *status = CSI_STATUS_REJECTED; + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (g_csi_param.current_state == CSI_STATE_START) { + wpa_driver_stop_csi_capture(bss, status); + alarm(0); + } + + g_csi_param.bss = bss; + cmd += 6; + next_arg = get_next_arg(cmd); + if (*next_arg != '\0' && *next_arg == ' ') + transport_mode = atoi(next_arg); + + if (transport_mode == 1 || transport_mode == -1) + transport_mode = 1; + g_csi_param.transport_mode = transport_mode; + + wpa_driver_start_csi_capture(bss, status, transport_mode); + if (*status == 0 && csi_duration > 0) { + signal(SIGALRM, stop_csi_callback); + alarm(csi_duration); + wpa_printf(MSG_DEBUG, "set alarm %ds done", csi_duration); + } + } else if (os_strncasecmp(cmd, "stop", 4) == 0) { + if (g_csi_param.current_state != CSI_STATE_START) + return WPA_DRIVER_OEM_STATUS_SUCCESS; + + wpa_driver_stop_csi_capture(bss, status); + wpa_printf(MSG_DEBUG, "stop csi cmd"); + } else { + wpa_printf(MSG_ERROR, "invalid command"); + *status = CSI_STATUS_REJECTED; + snprintf(buf, buf_len, "FAIL, Invalid command"); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} + +static int wpa_driver_restart_csi(struct i802_bss *bss, int *status) +{ + wpa_driver_send_get_scan_cmd(bss, status); + if (g_csi_param.connected_bssid[0] == 0xff) { + wpa_printf(MSG_DEBUG, "%s: Not connected", __func__); + *status = CSI_STATUS_REJECTED; + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + /* Stop CSI capture on previous bss */ + if(wpa_driver_stop_csi_capture(g_csi_param.bss, status)) { + wpa_printf(MSG_DEBUG, "%s: csi stop failed", __func__); + } + g_csi_param.bss = bss; + if(wpa_driver_start_csi_capture(g_csi_param.bss, status, + g_csi_param.transport_mode)) { + *status = CSI_STATUS_REJECTED; + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + *status = CSI_STATUS_SUCCESS; + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} + +/** + * twt_status_to_string() - Mapping twt response status into string + * @status: enum qca_wlan_vendor_twt_status values + * + * This function will map the twt response status into corresponding + * string. + * + * Return: pointer to the string + */ +static const char *twt_status_to_string(enum qca_wlan_vendor_twt_status status) +{ + switch (status) { + case QCA_WLAN_VENDOR_TWT_STATUS_OK: + return "QCA_WLAN_VENDOR_TWT_STATUS_OK"; + case QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED: + return "QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED"; + case QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID: + return "QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID"; + case QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY: + return "QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY"; + case QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST: + return "QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST"; + case QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED: + return "QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED"; + case QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM: + return "QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM"; + case QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY: + return "QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY"; + case QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE: + return "QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE"; + case QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK: + return "QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK"; + case QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE: + return "QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE"; + case QCA_WLAN_VENDOR_TWT_STATUS_DENIED: + return "QCA_WLAN_VENDOR_TWT_STATUS_DENIED"; + case QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: + return "QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR"; + case QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: + return "QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED"; + case QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: + return "QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID"; + case QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: + return "QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE"; + case QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: + return "QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE"; + case QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: + return "QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE"; + default: + return "INVALID TWT STATUS"; + } +} + +/** + * check_for_twt_cmd() - Check if the command string is a TWT command + * @cmd: Command string + * + * This function will identify a TWT operation in the command string + * and return one of the values in enum qca_wlan_twt_operation. + * + * Return: A valid TWT opertion if found, or error if not found + * + */ +static int check_for_twt_cmd(char **cmd) +{ + if (os_strncasecmp(*cmd, TWT_SETUP_STR, TWT_SETUP_STRLEN) == 0) { + *cmd += (TWT_SETUP_STRLEN + 1); + return QCA_WLAN_TWT_SET; + } else if (os_strncasecmp(*cmd, TWT_TERMINATE_STR, + TWT_TERMINATE_STR_LEN) == 0) { + *cmd += (TWT_TERMINATE_STR_LEN + 1); + return QCA_WLAN_TWT_TERMINATE; + } else if (os_strncasecmp(*cmd, TWT_PAUSE_STR, TWT_PAUSE_STR_LEN) == 0) { + *cmd += (TWT_PAUSE_STR_LEN + 1); + return QCA_WLAN_TWT_SUSPEND; + } else if (os_strncasecmp(*cmd, TWT_RESUME_STR, TWT_RESUME_STR_LEN) == 0) { + *cmd += (TWT_RESUME_STR_LEN + 1); + return QCA_WLAN_TWT_RESUME; + } else if (os_strncasecmp(*cmd, TWT_GET_PARAMS_STR, + TWT_GET_PARAMS_STR_LEN) == 0) { + *cmd += (TWT_GET_PARAMS_STR_LEN + 1); + return QCA_WLAN_TWT_GET; + } else if (os_strncasecmp(*cmd, TWT_NUDGE_STR, + TWT_NUDGE_STR_LEN) == 0) { + *cmd += (TWT_NUDGE_STR_LEN + 1); + return QCA_WLAN_TWT_NUDGE; + } else if (os_strncasecmp(*cmd, TWT_GET_STATS_STR, + TWT_GET_STATS_STR_LEN) == 0) { + *cmd += (TWT_GET_STATS_STR_LEN + 1); + return QCA_WLAN_TWT_GET_STATS; + } else if (os_strncasecmp(*cmd, TWT_CLEAR_STATS_STR, + TWT_CLEAR_STATS_STR_LEN) == 0) { + *cmd += (TWT_CLEAR_STATS_STR_LEN + 1); + return QCA_WLAN_TWT_CLEAR_STATS; + } else if (os_strncasecmp(*cmd, TWT_GET_CAP_STR, + TWT_GET_CAP_STR_LEN) == 0) { + *cmd += (TWT_GET_CAP_STR_LEN + 1); + return QCA_WLAN_TWT_GET_CAPABILITIES; + } else if (os_strncasecmp(*cmd, TWT_SET_PARAM_STR, + TWT_SET_PARAM_STR_LEN) == 0) { + *cmd += (TWT_SET_PARAM_STR_LEN + 1); + return QCA_WLAN_TWT_SET_PARAM; + } else { + wpa_printf(MSG_DEBUG, "Not a TWT command"); + return TWT_CMD_NOT_EXIST; + } +} + +static u64 get_u64_from_string(char *cmd_string, int *ret) +{ + u64 val = 0; + char *cmd = cmd_string; + + while (*cmd != ' ') + cmd++; + + *ret = 0; + errno = 0; + val = strtoll(cmd_string, NULL, 10); + if (errno == ERANGE || (errno != 0 && val == 0)) { + wpa_printf(MSG_ERROR, "invalid value"); + *ret = -EINVAL; + } + return val; +} + + +static u32 get_u32_from_string(char *cmd_string, int *ret) +{ + u32 val = 0; + char *cmd = cmd_string; + + while (*cmd != ' ') + cmd++; + + *ret = 0; + errno = 0; + val = strtol(cmd_string, NULL, 10); + if (errno == ERANGE || (errno != 0 && val == 0)) { + wpa_printf(MSG_ERROR, "invalid value"); + *ret = -EINVAL; + } + return val; +} + +static u8 get_u8_from_string(char *cmd_string, int *ret) +{ + char *cmd = cmd_string; + u8 val = 0; + + while (*cmd != ' ') + cmd++; + + *ret = 0; + errno = 0; + val = strtol(cmd_string, NULL, 10) & 0xFF; + if (errno == ERANGE || (errno != 0 && val == 0)) { + wpa_printf(MSG_ERROR, "invalid value"); + *ret = -EINVAL; + } + return val; +} + +char *move_to_next_str(char *cmd) +{ + if (*cmd == '\0') + return cmd; + + while (*cmd != ' ') { + cmd++; + if (*cmd == '\0') + return cmd; + } + + while (*cmd == ' ') + cmd++; + + return cmd; +} + +static int is_binary(u8 value) { + if(value == 0 || value == 1) + return 0; + return -1; +} + +static +void print_setup_cmd_values(struct twt_setup_parameters *twt_setup_params) +{ + wpa_printf(MSG_DEBUG, "TWT: setup dialog_id: %x", + twt_setup_params->dialog_id); + wpa_printf(MSG_DEBUG, "TWT: setup req type: %d ", + twt_setup_params->req_type); + wpa_printf(MSG_DEBUG, "TWT: setup trig type: %d ", + twt_setup_params->trig_type); + wpa_printf(MSG_DEBUG, "TWT: setup flow type: 0x%x", + twt_setup_params->flow_type); + wpa_printf(MSG_DEBUG, "TWT: setup wake exp: 0x%x", + twt_setup_params->wake_intr_exp); + wpa_printf(MSG_DEBUG, "TWT: setup protection: 0x%x", + twt_setup_params->protection); + wpa_printf(MSG_DEBUG, "TWT: setup wake time: 0x%x", + twt_setup_params->wake_time); + wpa_printf(MSG_DEBUG, "TWT: setup wake dur: 0x%x", + twt_setup_params->wake_dur); + wpa_printf(MSG_DEBUG, "TWT: setup wake intr mantissa: 0x%x", + twt_setup_params->wake_intr_mantissa); + wpa_printf(MSG_DEBUG, "TWT: setup bcast: %d ", + twt_setup_params->bcast); + wpa_printf(MSG_DEBUG, "TWT: min wake intvl: %d ", + twt_setup_params->min_wake_intvl); + wpa_printf(MSG_DEBUG, "TWT: max wake intvl: %d ", + twt_setup_params->max_wake_intvl); + wpa_printf(MSG_DEBUG, "TWT: min wake duration: %d ", + twt_setup_params->min_wake_duration); + wpa_printf(MSG_DEBUG, "TWT: max wake duration: %d ", + twt_setup_params->max_wake_duration); + wpa_printf(MSG_DEBUG, "TWT: wake tsf: 0x%lx ", + twt_setup_params->wake_tsf); + wpa_printf(MSG_DEBUG, "TWT: announce timeout(in us): %u", + twt_setup_params->announce_timeout_us); +} + +static int check_cmd_input(char *cmd_string) +{ + u32 cmd_string_len; + + if (!cmd_string) { + wpa_printf(MSG_ERROR, "cmd string null"); + return -EINVAL; + } + + cmd_string_len = strlen(cmd_string); + + wpa_printf(MSG_DEBUG, "TWT: cmd string - %s len = %u", cmd_string, + cmd_string_len); + if (cmd_string_len < DIALOG_ID_STR_LEN + SINGLE_SPACE_LEN + + SINGLE_DIGIT_LEN) { + wpa_printf(MSG_ERROR, "TWT: Dialog_id parameter missing"); + return -EINVAL; + } + + return 0; +} + +/** + * process_twt_setup_cmd_string() - Process a TWT setup command string + * @cmd: Command string + * @twt_setup_params: TWT setup parameters to fill + * + * This function parses the TWT setup command and populates twt_setup_params. + * + * Return: 0 on successs, error if invalid params are found + * + */ +static +int process_twt_setup_cmd_string(char *cmd, + struct twt_setup_parameters *twt_setup_params) +{ + int ret = 0; + + if (!twt_setup_params) { + wpa_printf(MSG_ERROR, "cmd or twt_setup_params null"); + return -EINVAL; + } + + if (check_cmd_input(cmd)) + return -EINVAL; + + wpa_printf(MSG_DEBUG, "process twt setup command string: %s", cmd); + while (*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += (DIALOG_ID_STR_LEN + 1); + twt_setup_params->dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (os_strncasecmp(cmd, REQ_TYPE_STR, REQ_TYPE_STR_LEN) == 0) { + cmd += (REQ_TYPE_STR_LEN + 1); + twt_setup_params->req_type = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (os_strncasecmp(cmd, TRIG_TYPE_STR, TRIG_TYPE_STR_LEN) == 0) { + cmd += (TRIG_TYPE_STR_LEN + 1); + twt_setup_params->trig_type = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (is_binary(twt_setup_params->trig_type)) { + wpa_printf(MSG_ERROR, "Invalid trigger type"); + return -EINVAL; + } + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, FLOW_TYPE_STR, FLOW_TYPE_STR_LEN) == 0) { + cmd += (FLOW_TYPE_STR_LEN + 1); + twt_setup_params->flow_type = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (is_binary(twt_setup_params->flow_type)) { + wpa_printf(MSG_ERROR, "Invalid flow type"); + return -EINVAL; + } + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, WAKE_INTR_EXP_STR, WAKE_INTR_EXP_STR_LEN) == 0) { + cmd += (WAKE_INTR_EXP_STR_LEN + 1); + twt_setup_params->wake_intr_exp = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (twt_setup_params->wake_intr_exp > + TWT_SETUP_WAKE_INTVL_EXP_MAX) { + wpa_printf(MSG_DEBUG, "Invalid wake_intr_exp %u", + twt_setup_params->wake_intr_exp); + return -EINVAL; + } + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, PROTECTION_STR, PROTECTION_STR_LEN) == 0) { + cmd += (PROTECTION_STR_LEN + 1); + twt_setup_params->protection = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (is_binary(twt_setup_params->protection)) { + wpa_printf(MSG_ERROR, "Invalid protection value"); + return -EINVAL; + } + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, WAKE_TIME_STR, WAKE_TIME_STR_LEN) == 0) { + cmd += (WAKE_TIME_STR_LEN + 1); + twt_setup_params->wake_time = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, WAKE_DUR_STR, WAKE_DUR_STR_LEN) == 0) { + cmd += (WAKE_DUR_STR_LEN + 1); + twt_setup_params->wake_dur = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (twt_setup_params->wake_dur == 0 || + twt_setup_params->wake_dur > TWT_SETUP_WAKE_DURATION_MAX) { + wpa_printf(MSG_ERROR, "Invalid wake_dura_us %u", + twt_setup_params->wake_dur); + return -EINVAL; + } + + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, WAKE_INTR_MANTISSA_STR, + WAKE_INTR_MANTISSA_STR_LEN) == 0) { + cmd += (WAKE_INTR_MANTISSA_STR_LEN + 1); + twt_setup_params->wake_intr_mantissa = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + if (twt_setup_params->wake_intr_mantissa > + TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) { + wpa_printf(MSG_ERROR, "Invalid wake_intr_mantissa %u", + twt_setup_params->wake_intr_mantissa); + return -EINVAL; + } + + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, BROADCAST_STR, BROADCAST_STR_LEN) == 0) { + cmd += (BROADCAST_STR_LEN + 1); + twt_setup_params->bcast = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (is_binary(twt_setup_params->bcast)) { + wpa_printf(MSG_ERROR, "Invalid broadcast value"); + return -EINVAL; + } + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, MIN_WAKE_INTVL_STR, MIN_WAKE_INTVL_STR_LEN) == 0) { + cmd += (MIN_WAKE_INTVL_STR_LEN + 1); + twt_setup_params->min_wake_intvl = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, MAX_WAKE_INTVL_STR, MAX_WAKE_INTVL_STR_LEN) == 0) { + cmd += (MAX_WAKE_INTVL_STR_LEN + 1); + twt_setup_params->max_wake_intvl = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, MIN_WAKE_DUR_STR, MIN_WAKE_DUR_STR_LEN) == 0) { + cmd += (MIN_WAKE_DUR_STR_LEN + 1); + twt_setup_params->min_wake_duration = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, MAX_WAKE_DUR_STR, MAX_WAKE_DUR_STR_LEN) == 0) { + cmd += (MAX_WAKE_DUR_STR_LEN + 1); + twt_setup_params->max_wake_duration = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, WAKE_TSF_STR, WAKE_TSF_STR_LEN) == 0) { + cmd += (WAKE_TSF_STR_LEN + 1); + twt_setup_params->wake_tsf = get_u64_from_string(cmd, &ret); + if(ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + if (strncmp(cmd, ANNOUNCE_TIMEOUT_STR, ANNOUNCE_TIMEOUT_STR_LEN) == 0) { + cmd += (ANNOUNCE_TIMEOUT_STR_LEN + 1); + twt_setup_params->announce_timeout_us = + get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + print_setup_cmd_values(twt_setup_params); + + return 0; +} + +static +int prepare_twt_setup_nlmsg(struct nl_msg *nlmsg, + struct twt_setup_parameters *twt_setup_params) +{ + struct nlattr *twt_attr; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_SET)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_SET"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + goto fail; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID, + twt_setup_params->dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + goto fail; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, + twt_setup_params->req_type)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put req type"); + goto fail; + } + + if (twt_setup_params->trig_type) { + if (nla_put_flag(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER) + ) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put trig type"); + goto fail; + } + } + + /*0 - Announced/ 1 - Unannounced*/ + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, + twt_setup_params->flow_type)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put flow type"); + goto fail; + } + + if (nla_put_u8(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP, + twt_setup_params->wake_intr_exp)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake exp"); + goto fail; + } + + if (twt_setup_params->protection) { + if (nla_put_flag(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) { + wpa_printf(MSG_DEBUG, + "TWT: Failed to add protection"); + goto fail; + } + } + + /*offset to add with TBTT after which 1st SP will start*/ + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME, + twt_setup_params->wake_time)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake time"); + goto fail; + } + + /*TWT Wake Duration in units of us, must be <= 65280*/ + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION, + twt_setup_params->wake_dur)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake dur"); + goto fail; + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA, + twt_setup_params->wake_intr_mantissa)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake intr mantissa"); + goto fail; + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA, + twt_setup_params->wake_intr_mantissa/TWT_WAKE_INTERVAL_TU_FACTOR)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake intr mantissa"); + goto fail; + } + + if (twt_setup_params->bcast) { + if (nla_put_flag(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put bcast"); + goto fail; + } + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL, + twt_setup_params->min_wake_intvl)) { + wpa_printf(MSG_ERROR, "TWT: Failed to put min wake intr "); + goto fail; + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL, + twt_setup_params->max_wake_intvl)) { + wpa_printf(MSG_ERROR,"TWT: Failed to put max wake intr"); + goto fail; + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION, + twt_setup_params->min_wake_duration)) { + wpa_printf(MSG_ERROR,"TWT: Failed to put min wake dur"); + goto fail; + } + + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION, + twt_setup_params->max_wake_duration)) { + wpa_printf(MSG_ERROR,"TWT: Failed to put max wake dur"); + goto fail; + } + + if (twt_setup_params->wake_tsf) { + if (nla_put_u64(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF, + twt_setup_params->wake_tsf)) { + wpa_printf(MSG_ERROR,"TWT: Failed to put wake time tsf value"); + goto fail; + } + } + + if (twt_setup_params->announce_timeout_us) { + if (nla_put_u32(nlmsg, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT, + twt_setup_params->announce_timeout_us)) { + wpa_printf(MSG_ERROR, "TWT: Failed to put announce timeout value"); + goto fail; + } + } + + nla_nest_end(nlmsg, twt_attr); + wpa_printf(MSG_DEBUG, "TWT: setup command nla end"); + return 0; + +fail: + return -EINVAL; +} + +static int prepare_twt_terminate_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + u8 dialog_id; + struct nlattr *twt_attr; + int ret = 0; + + if(check_cmd_input(cmd)) + return -EINVAL; + + while(*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += (DIALOG_ID_STR_LEN + 1); + dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + } else { + wpa_printf(MSG_ERROR, "TWT: no dialog_id found"); + goto fail; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_TERMINATE)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_TERMINATE"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + goto fail; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID, + dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + goto fail; + } + + nla_nest_end(nlmsg, twt_attr); + wpa_printf(MSG_DEBUG, "TWT: terminate sent with dialog_id: %x", + dialog_id); + + return 0; +fail: + return -EINVAL; +} + +static int prepare_twt_pause_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + u8 dialog_id; + struct nlattr *twt_attr; + int ret = 0; + + if(check_cmd_input(cmd)) + return -EINVAL; + + while(*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += (DIALOG_ID_STR_LEN + 1); + dialog_id = get_u8_from_string(cmd, &ret); + if(ret < 0) + return ret; + } else { + wpa_printf(MSG_ERROR, "TWT: no dialog_id found"); + goto fail; + } + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_SUSPEND)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_TERMINATE"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + goto fail; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID, + dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + goto fail; + } + + nla_nest_end(nlmsg, twt_attr); + wpa_printf(MSG_DEBUG, "TWT: pause sent with dialog_id: %x", dialog_id); + + return 0; +fail: + return -EINVAL; +} + +/** + * process_twt_resume_cmd_string() - Process a TWT resume command string + * @cmd: Command string + * @resume_params: TWT resume parameters to fill + * + * This function parses the TWT resume command and populates resume_params. + * + * Return: 0 on successs, error if invalid params are found + * + */ +static +int process_twt_resume_cmd_string(char *cmd, + struct twt_resume_parameters *resume_params) +{ + int ret = 0; + + if (!resume_params) { + wpa_printf(MSG_ERROR, "TWT: cmd or resume_params null"); + return -EINVAL; + } + + if(check_cmd_input(cmd)) + return -EINVAL; + + while(*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) != 0) { + wpa_printf(MSG_ERROR, "TWT: dialog ID parameter is required"); + return -EINVAL; + } + cmd += (DIALOG_ID_STR_LEN + 1); + resume_params->dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + + if (os_strncasecmp(cmd, NEXT_TWT_STR, NEXT_TWT_STR_LEN) == 0) { + cmd += (NEXT_TWT_STR_LEN + 1); + resume_params->next_twt = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + wpa_printf(MSG_DEBUG, "TWT: NEXT TWT %d", resume_params->next_twt); + cmd = move_to_next_str(cmd); + } + + if (os_strncasecmp(cmd, NEXT2_TWT_STR, NEXT2_TWT_STR_LEN) == 0) { + cmd += (NEXT2_TWT_STR_LEN + 1); + resume_params->next2_twt = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + wpa_printf(MSG_DEBUG, "TWT: NEXT2 TWT %d", resume_params->next2_twt); + cmd = move_to_next_str(cmd); + } + + if (os_strncasecmp(cmd, NEXT_TWT_SIZE_STR, NEXT_TWT_SIZE_STR_LEN) != 0) { + wpa_printf(MSG_ERROR, "TWT: next_twt_size parameter is required"); + return -EINVAL; + } + cmd += (NEXT_TWT_SIZE_STR_LEN + 1); + resume_params->next_twt_size = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + + return 0; +} + +static +int prepare_twt_resume_nlmsg(struct nl_msg *nlmsg, + struct twt_resume_parameters *resume_params) +{ + struct nlattr *twt_attr; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_RESUME)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_RESUME"); + return -EINVAL; + } + + twt_attr = nla_nest_start(nlmsg,QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + return -EINVAL; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID, + resume_params->dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + return -EINVAL; + } + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT, + resume_params->next_twt)) { + wpa_printf(MSG_DEBUG, "TWT: next_twt"); + return -EINVAL; + } + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT, + resume_params->next2_twt)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put next2_twt"); + return -EINVAL; + } + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE, + resume_params->next_twt_size)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put next_twt_size"); + return -EINVAL; + } + nla_nest_end(nlmsg, twt_attr); + + wpa_printf(MSG_DEBUG,"TWT: resume dialog_id: 0x%x next_twt (us): 0x%x next2_twt (us): 0x%x next_twt_size: %u", + resume_params->dialog_id, resume_params->next_twt, + resume_params->next2_twt,resume_params->next_twt_size); + + return 0; +} + +/** + * process_twt_nudge_cmd_string()- processes command string for nudge command. + * + * @Param cmd: expects the command + * @Param nudge_params: return parsed nudge parameters + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static +int process_twt_nudge_cmd_string(char *cmd, + struct twt_nudge_parameters *nudge_params) +{ + int ret = 0; + + if (!nudge_params) { + wpa_printf(MSG_ERROR, "TWT: nudge_params null"); + return -EINVAL; + } + + if(check_cmd_input(cmd)) + return -EINVAL; + + while(*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) != 0) { + wpa_printf(MSG_ERROR, "TWT: dialog_id parameter is required"); + return -EINVAL; + } + cmd += (DIALOG_ID_STR_LEN + 1); + nudge_params->dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + + if (os_strncasecmp(cmd, PAUSE_DURATION_STR, PAUSE_DURATION_STR_LEN) == 0) { + cmd += (PAUSE_DURATION_STR_LEN + 1); + nudge_params->wake_time = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + wpa_printf(MSG_DEBUG, "TWT: WAKE TIME %d", nudge_params->wake_time); + cmd = move_to_next_str(cmd); + } + + if (os_strncasecmp(cmd, NEXT_TWT_SIZE_STR, NEXT_TWT_SIZE_STR_LEN) != 0) { + wpa_printf(MSG_ERROR, "TWT: next_twt_size parameter is required"); + return -EINVAL; + } + cmd += (NEXT_TWT_SIZE_STR_LEN + 1); + nudge_params->next_twt_size = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + + return 0; +} + +/** + * prepare_twt_nudge_nlmsg()- prepare twt_session_nudge command . + * + * @Param nlmsg: nl command buffer + * @Param nudge_params: nudge parameters to prepare command + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static +int prepare_twt_nudge_nlmsg(struct nl_msg *nlmsg, + struct twt_nudge_parameters *nudge_params) +{ + struct nlattr *twt_attr; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_NUDGE)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put twt operation"); + return -EINVAL; + } + + twt_attr = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + return -EINVAL; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, + nudge_params->dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + return -EINVAL; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME, + nudge_params->wake_time)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put wake_time"); + return -EINVAL; + } + + if (nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE, + nudge_params->next_twt_size)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put next_twt_size"); + return -EINVAL; + } + nla_nest_end(nlmsg, twt_attr); + + wpa_printf(MSG_DEBUG,"TWT: nudge dialog_id: 0x%x wake_time(us): 0x%x next_twt_size: %u", + nudge_params->dialog_id, nudge_params->wake_time, + nudge_params->next_twt_size); + + return 0; +} + +/** + * process_twt_set_param_cmd_string()- processes command + * string for set parameters command. + * + * @Param cmd: expects the command + * @Param set_params: return parsed TWT set parameters + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static +int process_twt_set_param_cmd_string(char *cmd, + struct twt_set_parameters *set_params) +{ + int ret = -EINVAL; + + if (!set_params) { + wpa_printf(MSG_ERROR, "TWT: set_params null"); + return -EINVAL; + } + + if (check_cmd_input(cmd)) + return -EINVAL; + + while (*cmd == ' ') + cmd++; + + if (os_strncasecmp(cmd, AP_AC_VALUE_STR, AP_AC_VALUE_STR_LEN) == 0) { + cmd += (AP_AC_VALUE_STR_LEN + 1); + set_params->ap_ac_value = get_u8_from_string(cmd, &ret); + wpa_printf(MSG_DEBUG, "TWT: AP AC VALUE: %d", set_params->ap_ac_value); + if (ret < 0) + return ret; + cmd = move_to_next_str(cmd); + } + + return ret; +} + +/** + * prepare_twt_set_param_nlmsg()- prepare twt_set_param command . + * + * @Param nlmsg: nl command buffer + * @Param set_params: set parameters to prepare command + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static +int prepare_twt_set_param_nlmsg(struct nl_msg *nlmsg, + struct twt_set_parameters *set_params) +{ + struct nlattr *twt_attr; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_SET_PARAM)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put twt operation"); + return -EINVAL; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (!twt_attr) + return -EINVAL; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE, + set_params->ap_ac_value)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put ap_ac_value"); + return -EINVAL; + } + + nla_nest_end(nlmsg, twt_attr); + + wpa_printf(MSG_DEBUG, "TWT: set parameters - ap_ac_value: %d", + set_params->ap_ac_value); + + return 0; +} + +/** + * prepare_twt_clear_stats_nlmsg()- prepare twt_session_clear_stats command. + * + * @Param nlmsg: nl command buffer + * @Param cmd: command string + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static int prepare_twt_clear_stats_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + struct nlattr *twt_attr; + u8 dialog_id; + int ret = 0; + + while(*cmd == ' ') + cmd++; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_CLEAR_STATS)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_CLEAR_STATS"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (!twt_attr) + return -EINVAL; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += DIALOG_ID_STR_LEN + 1; + + dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID, + dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + return -EINVAL; + } + wpa_printf(MSG_DEBUG, "TWT: clear_stats dialog_id:%d", dialog_id); + cmd = move_to_next_str(cmd); + } else { + wpa_printf(MSG_DEBUG, "TWT: dialog_id not found"); + goto fail; + } + + nla_nest_end(nlmsg, twt_attr); + return 0; +fail: + return -EINVAL; +} + +/** + * prepare_twt_get_stats_nlmsg()- prepare twt_session_get_stats command. + * + * @Param nlmsg: nl command buffer + * @Param cmd: command string + * + * @Returns 0 on Success, -EINVAL on Failure + */ +static int prepare_twt_get_stats_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + struct nlattr *twt_attr; + u8 dialog_id; + int ret = 0; + + while(*cmd == ' ') + cmd++; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_GET_STATS)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_GET_STATS"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (!twt_attr) + return -EINVAL; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += DIALOG_ID_STR_LEN + 1; + + dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID, + dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + return -EINVAL; + } + wpa_printf(MSG_DEBUG, "TWT: get_stats dialog_id:%d", dialog_id); + cmd = move_to_next_str(cmd); + } else { + wpa_printf(MSG_DEBUG, "TWT: dialog_id not found"); + goto fail; + } + + nla_nest_end(nlmsg, twt_attr); + return 0; +fail: + return -EINVAL; +} + +static int prepare_twt_get_params_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + struct nlattr *twt_attr; + u8 dialog_id; + int ret = 0; + uint8_t peer_mac[MAC_ADDR_LEN]; + + while(*cmd == ' ') + cmd++; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_GET)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put QCA_WLAN_TWT_GET"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (!twt_attr) + return -EINVAL; + + if (os_strncasecmp(cmd, DIALOG_ID_STR, DIALOG_ID_STR_LEN) == 0) { + cmd += DIALOG_ID_STR_LEN + 1; + + dialog_id = get_u8_from_string(cmd, &ret); + if (ret < 0) + return ret; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID, + dialog_id)) { + wpa_printf(MSG_DEBUG, "TWT: Failed to put dialog_id"); + return -EINVAL; + } + wpa_printf(MSG_DEBUG, "TWT: get_param dialog_id:%d", dialog_id); + cmd = move_to_next_str(cmd); + } else { + wpa_printf(MSG_ERROR, "TWT: dialog_id not found"); + goto fail; + } + + + if (os_strncasecmp(cmd, MAC_ADDRESS_STR, MAC_ADDR_STR_LEN) == 0) { + cmd += MAC_ADDR_STR_LEN + 1; + + if (convert_string_to_bytes(peer_mac, cmd, MAC_ADDR_LEN) != + MAC_ADDR_LEN) { + wpa_printf(MSG_ERROR, "TWT: invalid mac address"); + goto fail; + } + + if (nla_put(nlmsg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR, + MAC_ADDR_LEN, peer_mac)) { + wpa_printf(MSG_ERROR, "TWT: Failed to put mac address"); + goto fail; + } + } + + nla_nest_end(nlmsg, twt_attr); + return 0; +fail: + return -EINVAL; +} + +/** +* prepare_twt_get_cap_nlmsg()- processes and packs get capability command. +* The command is expected in below format: +* TWT_GET_CAP +* +* @Param nlmsg: stores the nlmsg +* @Param cmd: expects the command +* +* @Returns 0 on Success, -EINVAL on Failure +*/ +static int prepare_twt_get_cap_nlmsg(struct nl_msg *nlmsg, char *cmd) +{ + struct nlattr *twt_attr; + + if (nla_put_u8(nlmsg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_GET_CAPABILITIES)) { + wpa_printf(MSG_ERROR,"TWT: Failed to put QCA_WLAN_TWT_GET_CAPABILITIES"); + goto fail; + } + + twt_attr = nla_nest_start(nlmsg, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS); + if (twt_attr == NULL) + goto fail; + nla_nest_end(nlmsg, twt_attr); + return 0; +fail: + return -EINVAL; +} + +static int pack_nlmsg_twt_params(struct nl_msg *twt_nl_msg, char *cmd, + enum qca_wlan_twt_operation type) +{ + struct nlattr *attr; + int ret = 0; + + attr = nla_nest_start(twt_nl_msg, NL80211_ATTR_VENDOR_DATA); + if (attr == NULL) + return -EINVAL; + + switch (type) { + case QCA_WLAN_TWT_SET: + { + struct twt_setup_parameters setup_params = {0}; + + if (process_twt_setup_cmd_string(cmd, &setup_params)) + return -EINVAL; + ret = prepare_twt_setup_nlmsg(twt_nl_msg, &setup_params); + break; + } + case QCA_WLAN_TWT_TERMINATE: + ret = prepare_twt_terminate_nlmsg(twt_nl_msg, cmd); + break; + case QCA_WLAN_TWT_SUSPEND: + ret = prepare_twt_pause_nlmsg(twt_nl_msg, cmd); + break; + case QCA_WLAN_TWT_RESUME: + { + struct twt_resume_parameters resume_params = {0}; + + if (process_twt_resume_cmd_string(cmd, &resume_params)) + return -EINVAL; + ret = prepare_twt_resume_nlmsg(twt_nl_msg, &resume_params); + break; + } + case QCA_WLAN_TWT_NUDGE: + { + struct twt_nudge_parameters nudge_params = {0}; + + if (process_twt_nudge_cmd_string(cmd, &nudge_params)) + return -EINVAL; + ret = prepare_twt_nudge_nlmsg(twt_nl_msg, &nudge_params); + break; + } + case QCA_WLAN_TWT_SET_PARAM: + { + struct twt_set_parameters set_params = {0}; + + if (process_twt_set_param_cmd_string(cmd, &set_params)) + return -EINVAL; + ret = prepare_twt_set_param_nlmsg(twt_nl_msg, &set_params); + break; + } + case QCA_WLAN_TWT_GET_CAPABILITIES: + ret = prepare_twt_get_cap_nlmsg(twt_nl_msg, cmd); + break; + case QCA_WLAN_TWT_CLEAR_STATS: + ret = prepare_twt_clear_stats_nlmsg(twt_nl_msg, cmd); + break; + case QCA_WLAN_TWT_GET_STATS: + ret = prepare_twt_get_stats_nlmsg(twt_nl_msg, cmd); + break; + case QCA_WLAN_TWT_GET: + ret = prepare_twt_get_params_nlmsg(twt_nl_msg, cmd); + break; + default: + wpa_printf(MSG_DEBUG, "Unsupported command: %d", type); + ret = -EINVAL; + break; + } + + if (!ret) + nla_nest_end(twt_nl_msg, attr); + + return ret; +} + +char *result_copy_to_buf(char *src, char *dst_buf, int *dst_len) +{ + int str_len, remaining = 0; + + remaining = *dst_len; + str_len = strlen(src); + remaining = remaining - (str_len + 1); + + if (remaining <= 0) { + wpa_printf(MSG_ERROR, "destination buffer length not enough"); + return NULL; + } + os_memcpy(dst_buf, src, str_len); + + *dst_len = remaining; + *(dst_buf + str_len) = ' '; + + return (dst_buf + str_len + 1); +} + +static int +unpack_twt_get_params_resp(struct nlattr **tb, char *buf, int buf_len) +{ + int cmd_id, val, len; + uint8_t exp; + uint32_t value; + unsigned long wake_tsf; + char temp[TWT_RESP_BUF_LEN]; + char *start = buf; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + + /* Mac Address */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no mac_addr"); + return -EINVAL; + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "<mac_addr " MAC_ADDR_STR, + MAC_ADDR_ARRAY((char *)nla_data(tb[cmd_id]))); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Flow Id */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no dialog_id"); + return -EINVAL; + } + val = nla_get_u8(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + + /* Broadcast */ + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST; + if (tb[cmd_id]) + val = nla_get_flag(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "bcast %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Trigger Type */ + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER; + if (tb[cmd_id]) + val = nla_get_flag(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "trig_type %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Announce */ + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE; + if (tb[cmd_id]) + val = nla_get_flag(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_type %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Protection */ + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION; + if (tb[cmd_id]) + val = nla_get_flag(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "protection %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* info */ + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED; + if (tb[cmd_id]) + val = nla_get_flag(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "info_enabled %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Wake Duration */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no wake duration"); + return -EINVAL; + } + value = nla_get_u32(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_dur %d", value); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Wake Interval Mantissa */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA; + if (!tb[cmd_id]) { + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no wake mantissa"); + return -EINVAL; + } + value = nla_get_u32(tb[cmd_id]); + value = value * TWT_WAKE_INTERVAL_TU_FACTOR; + } else { + value = nla_get_u32(tb[cmd_id]); + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_mantis %d", value); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* Wake Interval Exponent */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no wake intvl exp"); + return -EINVAL; + } + exp = nla_get_u8(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_exp %d", exp); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + /* TSF Value */ + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no wake time tsf"); + return -EINVAL; + } + wake_tsf = nla_get_u64(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_time_tsf 0x%lx>", wake_tsf); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE; + if (!tb[cmd_id]) { + wpa_printf(MSG_ERROR, "twt_get_params resp: no state info"); + return -EINVAL; + } + value = nla_get_u32(tb[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "state %d", value); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE; + if (tb[cmd_id]) { + val = nla_get_u8(tb[cmd_id]); + + os_snprintf(temp, TWT_RESP_BUF_LEN, "responder_pm %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + + len = (buf - start); + *buf = '\0'; + + return len; +} + +static int wpa_get_twt_setup_resp_val(struct nlattr **tb2, char *buf, + int buf_len) +{ + uint32_t wake_intvl_exp = 0, wake_intvl_mantis = 0; + int cmd_id, val; + uint32_t value; + unsigned long wake_tsf; + char temp[TWT_RESP_BUF_LEN]; + + buf = result_copy_to_buf(TWT_SETUP_RESP, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT dialog id missing"); + return -EINVAL; + } + + val = nla_get_u8(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %d ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT resp status missing"); + return -EINVAL; + } + + val = nla_get_u8(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "status %d ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val)); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT resp type missing"); + return -EINVAL; + } + val = nla_get_u8(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "resp_reason %d ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT_SETUP_WAKE_INTVL_EXP is must"); + return -EINVAL; + } + wake_intvl_exp = nla_get_u8(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl_exp %d ", + wake_intvl_exp); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST; + if (tb2[cmd_id]) + val = nla_get_flag(tb2[cmd_id]); + + os_snprintf(temp, TWT_RESP_BUF_LEN, "bcast %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER; + if (tb2[cmd_id]) + val = nla_get_flag(tb2[cmd_id]); + + os_snprintf(temp, TWT_RESP_BUF_LEN, "trig_type %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT_SETUP_FLOW_TYPE is must"); + return -EINVAL; + } + val = nla_get_u8(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_type %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION; + if (tb2[cmd_id]) + val = nla_get_flag(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "protection %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + value = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME; + if (tb2[cmd_id]) + value = nla_get_u32(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_time 0x%x", value); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "TWT_SETUP_WAKE_DURATION is must"); + return -EINVAL; + } + value = nla_get_u32(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_dur %d", value); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA; + if (!tb2[cmd_id]) { + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "SETUP_WAKE_INTVL_MANTISSA is must"); + return -EINVAL; + } + wake_intvl_mantis = nla_get_u32(tb2[cmd_id]); + wake_intvl_mantis = wake_intvl_mantis * TWT_WAKE_INTERVAL_TU_FACTOR; + } else { + wake_intvl_mantis = nla_get_u32(tb2[cmd_id]); + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_intvl %d", wake_intvl_mantis); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + wake_tsf = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF; + if (tb2[cmd_id]) + wake_tsf = nla_get_u64(tb2[cmd_id]); + os_snprintf(temp, TWT_RESP_BUF_LEN, "wake_tsf 0x%lx", wake_tsf); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED; + if (tb2[cmd_id]) + val = nla_get_flag(tb2[cmd_id]); + + os_snprintf(temp, TWT_RESP_BUF_LEN, "info_enabled %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + val = 0; + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE; + if (tb2[cmd_id]) { + val = nla_get_u8(tb2[cmd_id]); + + os_snprintf(temp, TWT_RESP_BUF_LEN, "responder_pm %d", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + + *buf = '\0'; + + return 0; +} + +/** + * unpack_twt_get_params_nlmsg()- unpacks and prints the twt get_param + * response recieved from driver synchronously for twt_session_get_params. + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -1 on Failure + */ +static int unpack_twt_get_params_nlmsg(struct nl_msg **tb, char *buf, int buf_len) +{ + int ret, rem, id, len = 0, num_twt_sessions = 0; + struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; + struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + struct nlattr *attr; + + if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX, + tb[NL80211_ATTR_VENDOR_DATA], NULL)) { + wpa_printf(MSG_ERROR, "twt_get_params: nla_parse_nested fail"); + return -EINVAL; + } + + id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS; + attr = config_attr[id]; + if (!attr) { + wpa_printf(MSG_ERROR, "twt_get_params: config_twt_params fail"); + return -EINVAL; + } + + num_twt_sessions = 0; + nla_for_each_nested(attr, config_attr[id], rem) { + num_twt_sessions++; + if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + nla_data(attr), nla_len(attr), NULL)) { + wpa_printf(MSG_ERROR, "twt_get_params: nla_parse fail"); + return -EINVAL; + } + ret = unpack_twt_get_params_resp(setup_attr, buf + len, + buf_len - len); + if (ret < 0) + return ret; + len += ret; + } + + wpa_printf(MSG_ERROR, "twt_get_params: number of twt sessions = %d", + num_twt_sessions); + + return 0; +} + +/** + * wpa_get_twt_stats_resp_val()- parse twt get_stats response + * recieved from driver synchronously for twt_session_get_stats. + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -1 on Failure + */ +static int wpa_get_twt_stats_resp_val(struct nlattr **tb2, char *buf, + int buf_len) +{ + int cmd_id, len; + u32 val = 0; + u8 val1 = 0; + char temp[TWT_RESP_BUF_LEN]; + char *start = buf; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats flow id missing", __func__); + } else { + val1 = nla_get_u8(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "flow_id %u", val1); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats flow id : %u", val1); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats num sp iterations missing", __func__); + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "num_sp_iteration %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT num sp Iterations : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats min wake duration missing", __func__); + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "min_wake_dur %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT min wake duration : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats max wake duration missing", __func__); + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "max_wake_dur %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT Max wake duration : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats sess_wake_dur missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "session_wake_dur %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats session wake duration : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats avg_wake_dur missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "avg_wake_dur %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats avg wake duration : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats average tx mpdu missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "tx_mpdu %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats average tx mpdu : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats average rx mpdu missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "rx_mpdu %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats average rx mpdu : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats average tx packet size missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "tx_pkt_size %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats average tx packet size : %u", val); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR,"%s TWT stats average rx packet size missing", __func__); + return -EINVAL; + } else { + val = nla_get_u32(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "rx_pkt_size %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + wpa_printf(MSG_INFO,"TWT stats average rx packet size : %u", val); + } + len = (buf - start); + *buf = '\0'; + + return len; +} + +/** + * unpack_twt_get_stats_nlmsg()- unpacks and prints the twt get_stats + * response recieved from driver synchronously for twt_session_get_stats. + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -1 on Failure + */ +static +int unpack_twt_get_stats_nlmsg(struct nl_msg **tb, char *buf, int buf_len) +{ + int ret, rem, id, len = 0, num_twt_sessions = 0; + struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; + struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + struct nlattr *attr; + + if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX, + tb[NL80211_ATTR_VENDOR_DATA], NULL)) { + wpa_printf(MSG_ERROR, "twt_get_stats: nla_parse_nested fail"); + return -EINVAL; + } + + id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS; + attr = config_attr[id]; + if (!attr) { + wpa_printf(MSG_ERROR, "twt_get_stats: config_twt_params fail"); + return -EINVAL; + } + + num_twt_sessions = 0; + nla_for_each_nested(attr, config_attr[id], rem) { + num_twt_sessions++; + if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + nla_data(attr), nla_len(attr), NULL)) { + wpa_printf(MSG_ERROR, "twt_get_stats: nla_parse fail"); + return -EINVAL; + } + ret = wpa_get_twt_stats_resp_val(setup_attr, buf + len, + buf_len - len); + if (ret < 0) + return ret; + len += ret; + } + wpa_printf(MSG_INFO,"twt_get_stats: number of twt sessions = %d", num_twt_sessions); + + return 0; +} + +static int wpa_get_twt_capabilities_resp_val(struct nlattr **tb2, char *buf, + int buf_len) +{ + int cmd_id; + u16 msb, lsb; + u32 val; + char temp[TWT_RESP_BUF_LEN]; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF; + if (!tb2[cmd_id]) { + wpa_printf(MSG_INFO,"%s TWT self capabilities missing", __func__); + return -EINVAL; + } else { + msb = nla_get_u16(tb2[cmd_id]); + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER; + if (!tb2[cmd_id]) { + wpa_printf(MSG_INFO,"%s TWT peer capabilities missing", __func__); + return -EINVAL; + } else { + lsb = nla_get_u16(tb2[cmd_id]); + } + wpa_printf(MSG_INFO,"TWT self_capab:%d, TWT peer_capab:%d", msb, lsb); + val = (msb << 16) | lsb; + os_snprintf(temp, TWT_RESP_BUF_LEN, "0x%x", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + *buf = '\0'; + + return 0; +} + +/** + * unpack_twt_get_capab_nlmsg()- unpacks and prints the twt get capabilities + * response recieved from driver synchronously for TWT_GET_CAP command. + * The response is printed in below hex-format: + * 0xHIGHLOW + * HIGH: Self capabilities + * LOW: Peer capabilities + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -1 on Failure + */ +static int unpack_twt_get_capab_nlmsg(struct nl_msg **tb, char *buf, int buf_len) +{ + int ret, id; + struct nlattr *config_attr[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; + struct nlattr *setup_attr[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + struct nlattr *attr; + + if (nla_parse_nested(config_attr, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX, + tb[NL80211_ATTR_VENDOR_DATA], NULL)) { + wpa_printf(MSG_ERROR, "twt_get_capability: nla_parse_nested fail"); + return -EINVAL; + } + + id = QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS; + attr = config_attr[id]; + if (!attr) { + wpa_printf(MSG_ERROR, "twt_get_capability: config_twt_params fail"); + return -EINVAL; + } + + if (nla_parse(setup_attr, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + nla_data(attr), nla_len(attr), NULL)) { + wpa_printf(MSG_ERROR, "twt_get_capability: nla_parse fail"); + return -EINVAL; + } + + ret = wpa_get_twt_capabilities_resp_val(setup_attr, buf, buf_len); + return ret; +} + +/** + * unpack_twt_setup_nlmsg()- unpacks twt_session_setup response recieved + * The response is printed in below format: + * CTRL-EVENT-TWT SETUP dialog_id <dialog_id> status <status> .. + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -EINVAL on invalid response + */ +static int unpack_twt_setup_nlmsg(struct nlattr **tb, char *buf, int buf_len) +{ + int ret = 0; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + + if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) { + wpa_printf(MSG_ERROR, "nla_parse failed\n"); + return -EINVAL; + } + + ret = wpa_get_twt_setup_resp_val(tb2, buf, buf_len); + + return ret; +} + +static int unpack_nlmsg_twt_params(struct nl_msg *twt_nl_msg, + enum qca_wlan_twt_operation type, + char *buf, int buf_len) +{ + int ret = 0; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(twt_nl_msg)); + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + switch (type) { + case QCA_WLAN_TWT_GET: + ret = unpack_twt_get_params_nlmsg(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_GET_STATS: + ret = unpack_twt_get_stats_nlmsg(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_GET_CAPABILITIES: + ret = unpack_twt_get_capab_nlmsg(tb, buf, buf_len); + break; + default: + wpa_printf(MSG_DEBUG, "Unsupported command: %d", type); + ret = -EINVAL; + break; + } + + return ret; +} + +static int twt_response_handler(struct nl_msg *msg, void *arg) +{ + struct twt_resp_info *info = (struct twt_resp_info *) arg; + struct wpa_driver_nl80211_data *drv = NULL; + int ret; + + drv = info->drv; + ret = unpack_nlmsg_twt_params(msg, info->twt_oper, info->reply_buf, + info->reply_buf_len); + wpa_printf(MSG_DEBUG, "%s - twt_oper %d", __func__, info->twt_oper); + if (!ret) + wpa_msg(drv->ctx, MSG_INFO, + TWT_CTRL_EVENT " %s : OK", info->reply_buf); + else + wpa_msg(drv->ctx, MSG_INFO, + TWT_CTRL_EVENT " %s : Error = %d", + info->reply_buf, ret); + + return ret; +} + +struct features_info { + u8 *flags; + size_t flags_len; +}; + +static +int check_feature(enum qca_wlan_vendor_features feature, + struct features_info *info) +{ + size_t idx = feature / 8; + + return (idx < info->flags_len) && + (info->flags[idx] & BIT(feature % 8)); +} + +/* features_info_handler() - parse sync response for get_feature cmd + * + * @param msg: nl_msg buffer + * @Param arg: feature infor + * + * @Returns 0 on Success, error code on invalid response + */ +static +int features_info_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *mHeader; + struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1]; + struct nlattr *vendata, *attr; + int datalen; + + struct features_info *info = (struct features_info *) arg; + int status = 0; + + + mHeader = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg)); + nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, + genlmsg_attrdata(mHeader, 0), + genlmsg_attrlen(mHeader, 0), NULL); + + if (mAttributes[NL80211_ATTR_VENDOR_DATA]) { + vendata = nla_data(mAttributes[NL80211_ATTR_VENDOR_DATA]); + datalen = nla_len(mAttributes[NL80211_ATTR_VENDOR_DATA]); + if (!vendata) { + wpa_printf(MSG_ERROR,"Vendor data not found"); + return -1; + } + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1]; + + nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX, + vendata, datalen, NULL); + + attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS]; + if (attr) { + int len = nla_len(attr); + info->flags = os_malloc(len); + if (info->flags != NULL) { + os_memcpy(info->flags, nla_data(attr), len); + info->flags_len = len; + } + } else { + wpa_printf(MSG_ERROR,"VENDOR_ATTR_FEATURE_FLAGS not found"); + } + } else { + wpa_printf(MSG_ERROR,"NL80211_ATTR_VENDOR_DATA not found"); + status = -1; + } + + return status; +} + +/* pack_nlmsg_vendor_feature_hdr() - pack get_features command + * + * @param drv_nl_msg: nl_msg buffer + * @Param drv: nl data + * @Param ifname: interface name + * + * @Returns 0 on Success, error code on invalid response + */ +static +int pack_nlmsg_vendor_feature_hdr(struct nl_msg *drv_nl_msg, + struct wpa_driver_nl80211_data *drv, + char *ifname) +{ + int ret; + int ifindex; + + genlmsg_put(drv_nl_msg, NL_AUTO_PORT, NL_AUTO_SEQ, + drv->global->nl80211_id, 0, 0, + NL80211_CMD_VENDOR, 0); + + ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_VENDOR_ID, OUI_QCA); + if (ret < 0) { + wpa_printf(MSG_ERROR, "Failed to put vendor id"); + return ret; + } + + ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES); + if (ret < 0) { + wpa_printf(MSG_DEBUG, "nl put twt vendor subcmd failed"); + return ret; + } + + if (ifname && (strlen(ifname) > 0)) + ifindex = if_nametoindex(ifname); + else + ifindex = if_nametoindex(DEFAULT_IFNAME); + + ret = nla_put_u32(drv_nl_msg, NL80211_ATTR_IFINDEX, ifindex); + if (ret < 0) { + wpa_printf(MSG_DEBUG, "nl put iface: %s failed", ifname); + return ret; + } + return ret; +} + +/* check_wifi_twt_async_feature() - check if driver supports twt async feature + * + * @Param drv: nl data + * @Param ifname: interface name + * + * @Returns 1 if twt async feature is supported, 0 otherwise + */ +static int check_wifi_twt_async_feature(struct wpa_driver_nl80211_data *drv, + char *ifname) +{ + struct nl_msg *nlmsg; + struct features_info info; + int ret; + + if (twt_async_support != -1) { + return twt_async_support; + } + + nlmsg = nlmsg_alloc(); + if (!nlmsg) { + wpa_printf(MSG_ERROR, "nlmg alloc failure"); + return -ENOMEM; + } + + pack_nlmsg_vendor_feature_hdr(nlmsg, drv, ifname); + os_memset(&info, 0, sizeof(info)); + ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + features_info_handler, &info); + + if (ret || !info.flags) { + nlmsg_free(nlmsg); + return 0; + } + + if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info)) { + twt_async_support = 1; + } else { + twt_async_support = 0; + } + + os_free(info.flags); + return twt_async_support; +} + +static int wpa_driver_twt_cmd_handler(struct wpa_driver_nl80211_data *drv, + char *ifname, + enum qca_wlan_twt_operation twt_oper, + char *param, char *buf, + size_t buf_len, int *status) +{ + struct nl_msg *twt_nl_msg; + struct twt_resp_info reply_info; + int ret = 0; + + if (!param) { + wpa_printf(MSG_ERROR, "%s:TWT cmd args missing\n", __func__); + return -EINVAL; + } + + if (!buf) { + wpa_printf(MSG_ERROR, "buf is NULL"); + return -EINVAL; + } + + wpa_printf(MSG_DEBUG, "TWT DRIVER cmd: %s", param); + + memset(&reply_info, 0, sizeof(struct twt_resp_info)); + os_memset(buf, 0, buf_len); + + reply_info.twt_oper = twt_oper; + reply_info.reply_buf = buf; + reply_info.reply_buf_len = buf_len; + reply_info.drv = drv; + + twt_nl_msg = prepare_nlmsg(drv, ifname, NL80211_CMD_VENDOR, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT, 0); + if (!twt_nl_msg) { + ret = -EINVAL; + goto err_msg; + } + + ret = pack_nlmsg_twt_params(twt_nl_msg, param, twt_oper); + if (ret) { + nlmsg_free(twt_nl_msg); + goto err_msg; + } + + switch(twt_oper) { + case QCA_WLAN_TWT_GET: + case QCA_WLAN_TWT_GET_CAPABILITIES: + case QCA_WLAN_TWT_GET_STATS: + *status = send_nlmsg((struct nl_sock *)drv->global->nl, + twt_nl_msg, twt_response_handler, + &reply_info); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status); + ret = -EINVAL; + } + break; + case QCA_WLAN_TWT_CLEAR_STATS: + *status = send_nlmsg((struct nl_sock *)drv->global->nl, + twt_nl_msg, NULL, NULL); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status); + ret = -EINVAL; + } + break; + case QCA_WLAN_TWT_SET: + case QCA_WLAN_TWT_TERMINATE: + case QCA_WLAN_TWT_SUSPEND: + case QCA_WLAN_TWT_RESUME: + case QCA_WLAN_TWT_NUDGE: + case QCA_WLAN_TWT_SET_PARAM: + if(check_wifi_twt_async_feature(drv, ifname) == 0) { + wpa_printf(MSG_ERROR, "Asynchronous TWT Feature is missing"); + ret = -EINVAL; + } else { + *status = send_nlmsg((struct nl_sock *)drv->global->nl, + twt_nl_msg, NULL, NULL); + if (*status != 0) { + wpa_printf(MSG_ERROR, "Failed to send nlmsg - err %d", *status); + ret = -EINVAL; + } + } + break; + default: + wpa_printf(MSG_ERROR, "nlmg send failure"); + ret = -EINVAL; + goto err_msg; + } + +err_msg: + wpa_printf(MSG_ERROR, "sent nlmsg - status %d", *status); + return ret; +} + +/** + * unpack_twt_terminate_event()- unpacks twt_session_terminate response recieved + * The response is printed in below format: + * CTRL-EVENT-TWT TERMINATE dialog_id <dialog_id> status <status> + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -EINVAL on invalid response + */ +static +int unpack_twt_terminate_event(struct nlattr **tb, char *buf, int buf_len) +{ + int cmd_id; + u8 val; + char temp[TWT_RESP_BUF_LEN]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + + if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) { + wpa_printf(MSG_ERROR, "nla_parse failed"); + return -EINVAL; + } + + buf = result_copy_to_buf(TWT_TEARDOWN_RESP, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_TEARDOWN_RESP_LEN); + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + if(val == 255) { + val = 0; + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val)); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + *buf = '\0'; + + return 0; +} + +/** + * unpack_twt_suspend_event()- unpacks twt_session_pause response recieved + * The response is printed in below format: + * CTRL-EVENT-TWT PAUSE dialog_id <dialog_id> status <status> + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -EINVAL on invalid response + */ +static +int unpack_twt_suspend_event(struct nlattr **tb, char *buf, int buf_len) +{ + int cmd_id; + u8 val; + char temp[TWT_RESP_BUF_LEN]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + + if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) { + wpa_printf(MSG_ERROR, "nla_parse failed"); + return -1; + } + + buf = result_copy_to_buf(TWT_PAUSE_RESP, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_PAUSE_RESP_LEN); + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + if(val == 255) { + val = 0; + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val)); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + *buf = '\0'; + + return 0; +} + +/** + * unpack_twt_resume_event()- unpacks twt_session_resume response recieved + * The response is printed in below format: + * CTRL-EVENT-TWT RESUME dialog_id <dialog_id> status <status> + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -EINVAL on invalid response + */ +static +int unpack_twt_resume_event(struct nlattr **tb, char *buf, int buf_len) +{ + int cmd_id; + u8 val; + char temp[TWT_RESP_BUF_LEN]; + struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1]; + + if (nla_parse_nested(tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX, + tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS], NULL)) { + wpa_printf(MSG_ERROR, "nla_parse failed"); + return -1; + } + + buf = result_copy_to_buf(TWT_RESUME_RESP, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESUME_RESP_LEN); + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT dialog id missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + if(val == 255) { + val = 0; + } + os_snprintf(temp, TWT_RESP_BUF_LEN, "dialog_id %u", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + + cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS; + if (!tb2[cmd_id]) { + wpa_printf(MSG_ERROR, "%s TWT resp status missing", __func__); + return -EINVAL; + } else { + val = nla_get_u8(tb2[cmd_id]); + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "status %u ", val); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + os_snprintf(temp, TWT_RESP_BUF_LEN, "(%s)", twt_status_to_string(val)); + buf = result_copy_to_buf(temp, buf, &buf_len); + if (!buf) + return -EINVAL; + } + *buf = '\0'; + + return 0; +} + +/** + * unpack_twt_notify_event()- prints the twt notify response recieved from driver + * asynchronously for QCA_WLAN_TWT_SETUP_READY_NOTIFY event. + * The response is printed in below format: + * CTRL-EVENT-TWT NOTIFY + * + * @Param tb: vendor nl data + * @Param buf: stores the response + * @Param buf_len: length of the response buffer + * + * @Returns 0 on Success, -EINVAL on invalid response + */ +int unpack_twt_notify_event(struct nlattr **tb, char *buf, int buf_len) +{ + char temp[TWT_RESP_BUF_LEN]; + + os_memset(temp, 0, TWT_RESP_BUF_LEN); + + buf = result_copy_to_buf(TWT_NOTIFY_RESP, buf, &buf_len); + if (!buf) + return -EINVAL; + + *buf = '\0'; + return 0; +} + +/** + * wpa_driver_twt_async_resp_handler()- handler for asynchronous twt vendor event + * recieved from the driver. + * + * @Param drv- wpa_driver_nl80211_data + * @Param vendor_id- vendor id for vendor specific command + * @Param subcmd- subcmd as defined by enum qca_nl80211_vendor_subcmds + * @Param data- vendor data + * @Param len- vendor data length + * + * @Returns 0 for Success, -1 for Failure + */ +static int wpa_driver_twt_async_resp_event(struct wpa_driver_nl80211_data *drv, + u32 vendor_id, u32 subcmd, u8 *data, size_t len) +{ + int ret = 0; + char *buf; + buf = (char *)malloc(TWT_RESP_BUF_LEN); + int buf_len = TWT_RESP_BUF_LEN; + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1]; + u8 twt_operation_type; + + if (!buf) + return -1; + + ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX, + (struct nlattr *) data, len, NULL); + if (ret) { + wpa_printf(MSG_ERROR, "nla_parse failed %d", ret); + goto fail; + } + + if (!buf) { + wpa_printf(MSG_ERROR, "buf not allocated"); + return -1; + } + + memset(buf, 0, TWT_RESP_BUF_LEN); + + twt_operation_type = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]); + + switch(twt_operation_type) { + case QCA_WLAN_TWT_SET: + ret = unpack_twt_setup_nlmsg(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_TERMINATE: + ret = unpack_twt_terminate_event(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_SUSPEND: + ret = unpack_twt_suspend_event(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_RESUME: + ret = unpack_twt_resume_event(tb, buf, buf_len); + break; + case QCA_WLAN_TWT_SETUP_READY_NOTIFY: + ret = unpack_twt_notify_event(tb, buf, buf_len); + break; + default: + ret = -1; + } + + if(ret) { + wpa_printf(MSG_ERROR, "Async event parsing failed for operation %d", + twt_operation_type); + goto fail; + } + wpa_printf(MSG_ERROR,"%s", buf); + wpa_msg(drv->ctx, MSG_INFO, "%s", buf); +fail: + free(buf); + return ret; +} + +static int wpa_driver_form_clear_mcc_quota_msg(struct i802_bss *bss, + char *cmd) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nlattr *nl_attr; + struct nl_msg *nlmsg; + uint32_t if_index = 0; + int ret; + + /* First comes interface name - optional */ + if (os_strncasecmp(cmd, "iface", 5) == 0) { + char *iface; + cmd = move_to_next_str(cmd); + /* null terminate the iface name in the cmd string */ + iface = strchr(cmd, ' '); + if (iface == NULL) { + wpa_printf(MSG_ERROR, "mcc_quota: iface is not found" + " in cmd string"); + return -EINVAL; + } + *iface = '\0'; + iface = cmd; + errno = 0; + if_index = if_nametoindex(cmd); + if (if_index == 0) { + wpa_printf(MSG_ERROR, "mcc_quota: iface %s not found %d", + cmd, errno); + return -EINVAL; + } + wpa_printf(MSG_INFO, "mcc_quota: ifindex %u", if_index); + cmd += strlen(iface) + 1; + } + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA); + if (!nlmsg) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to allocate nl message"); + return -ENOMEM; + } + + nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!nl_attr) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc nlattr"); + ret = -ENOMEM; + goto fail; + } + /* Put the quota type */ + ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR); + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to add type attr %d", ret); + goto fail; + } + + if (if_index) { + ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX, if_index); + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to add if_index attr %d", ret); + goto fail; + } + } + nla_nest_end(nlmsg, nl_attr); + + ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL); + + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret); + goto fail; + } + + return 0; +fail: + nlmsg_free(nlmsg); + return ret; +} + +static int wpa_driver_form_set_mcc_quota_msg(struct i802_bss *bss, + char *cmd) +{ + struct wpa_driver_nl80211_data *drv = bss->drv; + struct mcc_quota mccquota[MCC_QUOTA_ENTRIES_MAX]; + uint32_t if_index, quota; + struct nlattr *nl_attr, *mcc_attr_list; + struct nlattr *mcc_attr; + struct nl_msg *nlmsg; + int ret, entry, i; + + wpa_printf(MSG_INFO, "mcc_quota: %s", cmd); + + entry = 0; + while (*cmd != '\0') { + if (entry >= MCC_QUOTA_ENTRIES_MAX) { + wpa_printf(MSG_INFO, "mcc_quota: Only %d entries accepted", entry); + break; + } + /* First comes interface name */ + if (os_strncasecmp(cmd, "iface", 5) == 0) { + char *iface; + cmd = move_to_next_str(cmd); + /* null terminate the iface name in the cmd string */ + iface = strchr(cmd, ' '); + if (iface == NULL) { + wpa_printf(MSG_ERROR, "mcc_quota: iface is not" + " found in cmd string"); + return -EINVAL; + } + *iface = '\0'; + iface = cmd; + errno = 0; + if_index = if_nametoindex(cmd); + if (if_index == 0) { + wpa_printf(MSG_ERROR, "mcc_quota: iface %s not found %d", + cmd, errno); + return -EINVAL; + } + wpa_printf(MSG_INFO, "mcc_quota: ifindex %u", if_index); + cmd += strlen(iface) + 1; + } else { + wpa_printf(MSG_ERROR, "mcc_quota: Iface name not in order"); + return -EINVAL; + } + + /* Second comes quota value */ + if (os_strncasecmp(cmd, "quota", 5) == 0) { + cmd = move_to_next_str(cmd); + quota = get_u32_from_string(cmd, &ret); + if (ret < 0) + return ret; + } else { + wpa_printf(MSG_ERROR, "mcc_quota: Quota not in order"); + return -EINVAL; + } + + if (quota < MCC_QUOTA_MIN || quota > MCC_QUOTA_MAX) { + wpa_printf(MSG_ERROR, "mcc_quota: Invalid quota value %u", quota); + return -EINVAL; + } + + mccquota[entry].if_idx = if_index; + mccquota[entry].quota = quota; + cmd = move_to_next_str(cmd); + entry++; + } + wpa_printf(MSG_INFO, "mcc_quota: Entries : %d", entry); + if (entry < 1) { + wpa_printf(MSG_ERROR, "mcc_quota: No valid entries?"); + return -EINVAL; + } + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"mcc_quota: Failed to allocate nl message"); + return -ENOMEM; + } + + nl_attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (nl_attr == NULL) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc nlattr"); + ret = -ENOMEM; + goto fail; + } + + /* Put the quota type */ + ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED); + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to add type attr %d", ret); + goto fail; + } + + mcc_attr_list = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES); + if (!mcc_attr_list) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc mcc_attr_list"); + ret = -ENOMEM; + goto fail; + } + + for (i = 0; i < entry && entry <= MCC_QUOTA_ENTRIES_MAX; i++) { + /* Nest the (iface ,quota) */ + mcc_attr = nla_nest_start(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES); + if (mcc_attr == NULL) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to alloc mccattr"); + ret = -ENOMEM; + goto fail; + } + ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX, mccquota[i].if_idx); + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to add if_index attr %d", ret); + goto fail; + } + + ret = nla_put_u32(nlmsg, QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE, mccquota[i].quota); + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Failed to add quota attr %d", ret); + goto fail; + } + + nla_nest_end(nlmsg, mcc_attr); + } + nla_nest_end(nlmsg, mcc_attr_list); + + nla_nest_end(nlmsg, nl_attr); + + ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, NULL, NULL); + + if (ret) { + wpa_printf(MSG_ERROR, "mcc_quota: Error sending nlmsg %d", ret); + goto fail; + } + + return 0; +fail: + nlmsg_free(nlmsg); + return ret; +} + +int wpa_driver_cmd_send_mcc_quota(struct i802_bss *bss, + char *cmd) +{ + int ret; + + wpa_printf(MSG_INFO, "mcc_quota: %s", cmd); + + if (os_strncasecmp(cmd, "set", 3) == 0) { + cmd = move_to_next_str(cmd); + ret = wpa_driver_form_set_mcc_quota_msg(bss, cmd); + return ret; + } + + if (os_strncasecmp(cmd, "clear", 5) == 0) { + cmd = move_to_next_str(cmd); + ret = wpa_driver_form_clear_mcc_quota_msg(bss, cmd); + return ret; + } + + wpa_printf(MSG_ERROR, "mcc_quota: Unknown operation"); + return -EINVAL; +} + +int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, + size_t buf_len ) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = NULL; + struct wpa_driver_nl80211_data *driver; + struct ifreq ifr; + android_wifi_priv_cmd priv_cmd; + int ret = 0, status = 0, lib_n = 0; + + if (bss) { + drv = bss->drv; + } else { + if (os_strncasecmp(cmd, "SET_AP_SUSPEND", 14)) { + wpa_printf(MSG_ERROR, "%s: bss is NULL for cmd %s\n", + __func__, cmd); + return -EINVAL; + } + } + + if (wpa_driver_oem_initialize(&oem_cb_table) != WPA_DRIVER_OEM_STATUS_FAILURE && + oem_cb_table) { + + for (lib_n = 0; + oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL; + lib_n++) + { + ret = oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb( + priv, cmd, buf, buf_len, &status); + if (ret == WPA_DRIVER_OEM_STATUS_SUCCESS ) { + return strlen(buf); + } else if (ret == WPA_DRIVER_OEM_STATUS_ENOSUPP) { + continue; + } else if ((ret == WPA_DRIVER_OEM_STATUS_FAILURE) && + (status != 0)) { + wpa_printf(MSG_DEBUG, "%s: Received error: %d", + __func__, status); + return status; + } + } + /* else proceed with legacy handling as below */ + } + + if (!drv) { + wpa_printf(MSG_ERROR, "%s: drv is NULL for cmd %s\n", + __func__, cmd); + return -EINVAL; + } + + if (os_strcasecmp(cmd, "START") == 0) { + dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) { + linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 1); + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); + } + } else if (os_strcasecmp(cmd, "MACADDR") == 0) { + u8 macaddr[ETH_ALEN] = {}; + + ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr); + if (!ret) + ret = os_snprintf(buf, buf_len, + "Macaddr = " MACSTR "\n", MAC2STR(macaddr)); + } else if (os_strncasecmp(cmd, "SET_CONGESTION_REPORT ", 22) == 0) { + return wpa_driver_cmd_set_congestion_report(priv, cmd + 22); + } else if (os_strncasecmp(cmd, "SET_TXPOWER ", 12) == 0) { + return wpa_driver_cmd_set_tx_power(priv, cmd + 12); + } else if (os_strncasecmp(cmd, "CSI", 3) == 0) { + cmd += 3; + return wpa_driver_handle_csi_cmd(bss, cmd, buf, buf_len, &status); + } else if(os_strncasecmp(cmd, "GETSTATSBSSINFO", 15) == 0) { + + struct resp_info info,info2; + struct nl_msg *nlmsg; + struct nlattr *attr; + + os_memset(&g_bss_info, 0, sizeof(struct bss_info)); + + memset(&info, 0, sizeof(struct resp_info)); + memset(&info2, 0, sizeof(struct resp_info)); + + info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION; + info.cmd_type = GETSTATSBSSINFO; + char *p; + if(wpa_driver_ioctl(bss, "GETCOUNTRYREV", buf, buf_len, &status, drv) == 0){ + p = strstr(buf, " "); + if(p != NULL) + memcpy(info.country, (p+1), strlen(p+1)+1);//length of p including null + } + cmd += 16; + os_memset(buf, 0, buf_len); + + u8 mac[MAC_ADDR_LEN]; + + cmd = skip_white_space(cmd); + + if (strlen(cmd) >= MAC_ADDR_LEN * 2 + MAC_ADDR_LEN - 1 + && convert_string_to_bytes(mac, cmd, MAC_ADDR_LEN) > 0) { + wpa_printf(MSG_INFO,"invoking QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO to retrieve new attributes"); + os_memcpy(&info2.mac_addr[0], mac, MAC_ADDR_LEN); + nlmsg = prepare_vendor_nlmsg(bss->drv, bss->ifname, + QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + attr = nla_nest_start(nlmsg, NL80211_ATTR_VENDOR_DATA); + if (!attr) { + nlmsg_free(nlmsg); + return -1; + } + + if (nla_put(nlmsg, GET_STA_INFO_MAC, + MAC_ADDR_LEN, mac)) { + wpa_printf(MSG_ERROR,"Failed to put GET_STA_INFO_MAC"); + nlmsg_free(nlmsg); + return -1; + } + + nla_nest_end(nlmsg, attr); + + ret = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + get_sta_info_handler, &info2); + if (ret != 0) { + if (ret == -EOPNOTSUPP) { + wpa_printf(MSG_INFO,"Command is not supported, sending -1 for all new vendor attributes"); + } else { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", ret); + return -1; + } + g_bss_info.ani_level = -1; + g_bss_info.roam_trigger_reason = -1; + g_bss_info.roam_fail_reason = -1; + g_bss_info.roam_invoke_fail_reason = -1; + g_bss_info.tsf_out_of_sync_count = -1; + g_bss_info.latest_tx_power = -1; + g_bss_info.latest_tx_rate = -1; + g_bss_info.target_power_24g_1mbps = -1; + g_bss_info.target_power_24g_6mbps = -1; + g_bss_info.target_power_5g_6mbps = -1; + } else { + wpa_printf(MSG_INFO,"Command successfully invoked"); + g_bss_info.ani_level = g_sta_info.ani_level; + g_bss_info.roam_trigger_reason = g_sta_info.roam_trigger_reason; + g_bss_info.roam_fail_reason = g_sta_info.roam_fail_reason; + g_bss_info.roam_invoke_fail_reason = g_sta_info.roam_invoke_fail_reason; + g_bss_info.tsf_out_of_sync_count = g_sta_info.tsf_out_of_sync_count; + g_bss_info.latest_tx_power = g_sta_info.latest_tx_power; + g_bss_info.latest_tx_rate = g_sta_info.latest_tx_rate; + g_bss_info.target_power_24g_1mbps = g_sta_info.target_power_24g_1mbps; + g_bss_info.target_power_24g_6mbps = g_sta_info.target_power_24g_6mbps; + g_bss_info.target_power_5g_6mbps = g_sta_info.target_power_5g_6mbps; + } + } + + info.reply_buf = buf; + info.reply_buf_len = buf_len; + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + info.subcmd); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + if (populate_nlmsg(nlmsg, cmd, info.cmd_type)) { + wpa_printf(MSG_ERROR,"Failed to populate nl message"); + nlmsg_free(nlmsg); + return -1; + } + + status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + response_handler, &info); + if (status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status); + return -1; + } + + return strlen(info.reply_buf); + } else if (os_strncasecmp(cmd, "GETSTATSSTAINFO", 15) == 0) { + cmd += 15; + return wpa_driver_handle_get_sta_info(bss, cmd, buf, buf_len, + &status); + } else if (os_strncasecmp(cmd, "SETCELLSWITCHMODE", 17) == 0) { + cmd += 17; + struct resp_info info; + struct nl_msg *nlmsg; + + memset(&info, 0, sizeof(struct resp_info)); + + info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM; + info.cmd_type = SETCELLSWITCHMODE; + + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + info.subcmd); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + if (populate_nlmsg(nlmsg, cmd, info.cmd_type)) { + wpa_printf(MSG_ERROR,"Failed to populate nl message"); + nlmsg_free(nlmsg); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + NULL, NULL); + if (status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + return WPA_DRIVER_OEM_STATUS_SUCCESS; + } else if (os_strncasecmp(cmd, "SET_ANI_LEVEL ", 14) == 0) { + char *endptr = NULL; + int mode = 0; + int ofdmlvl = 0; + mode = strtol(cmd + 14, &endptr, 10); + if (mode == 1) { + if(!(*endptr)) { + wpa_printf(MSG_ERROR, "%s: failed to set ani setting,\ + invalid cmd: %s\n", __func__, cmd); + return -EINVAL; + } + ofdmlvl = strtol(endptr, NULL, 10); + } + return wpa_driver_cmd_set_ani_level(priv, mode, ofdmlvl); + } else if (os_strncasecmp(cmd, "GET_THERMAL_INFO", 16) == 0) { + int temperature = -1; + int thermal_state = -1; + int ret, ret2; + + ret = wpa_driver_cmd_get_thermal_info(priv, &temperature, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE); + if (ret) + return -1; + ret2 = wpa_driver_cmd_get_thermal_info(priv, &thermal_state, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL); + if (ret2) + return -1; + + snprintf(buf, buf_len, "%d %d", temperature, thermal_state); + return strlen(buf); + } else if (os_strncasecmp(cmd, "GET_DRIVER_SUPPORTED_FEATURES", 29) == 0) { + struct resp_info info; + struct nl_msg *nlmsg; + memset(&info, 0, sizeof(struct resp_info)); + info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES; + os_memset(buf, 0, buf_len); + info.reply_buf = buf; + info.reply_buf_len = buf_len; + nlmsg = prepare_vendor_nlmsg(drv, bss->ifname, + info.subcmd); + if (!nlmsg) { + wpa_printf(MSG_ERROR,"Failed to allocate nl message"); + return -1; + } + + status = send_nlmsg((struct nl_sock *)drv->global->nl, nlmsg, + response_handler, &info); + if (status != 0) { + wpa_printf(MSG_ERROR,"Failed to send nl message with err %d", status); + return -1; + } + + return WPA_DRIVER_OEM_STATUS_SUCCESS; + } else if ((ret = check_for_twt_cmd(&cmd)) != TWT_CMD_NOT_EXIST) { + enum qca_wlan_twt_operation twt_oper = ret; + u8 is_twt_feature_supported = 0; + + if (oem_cb_table) { + for (lib_n = 0; + oem_cb_table[lib_n].wpa_driver_driver_cmd_oem_cb != NULL; + lib_n++) + { + if (oem_cb_table[lib_n].wpa_driver_oem_feature_check_cb) { + if (oem_cb_table[lib_n].wpa_driver_oem_feature_check_cb(FEATURE_TWT_SUPPORT)) + is_twt_feature_supported = 1; + break; + } + } + } + + if (is_twt_feature_supported) { + wpa_printf(MSG_ERROR, "%s: TWT feature already supported by oem lib %d\n", __func__, lib_n); + ret = -EINVAL; + } else { + ret = wpa_driver_twt_cmd_handler(drv, bss->ifname, twt_oper, cmd, buf, buf_len, + &status); + if (ret) + ret = os_snprintf(buf, buf_len, "TWT failed for operation %d", twt_oper); + } + } else if (os_strncasecmp(cmd, "MCC_QUOTA", 9) == 0) { + /* DRIVER MCC_QUOTA set iface <name> quota <val> + * DRIVER MCC_QUOTA clear iface <name> + */ + /* Move cmd by string len and space */ + cmd += 10; + return wpa_driver_cmd_send_mcc_quota(priv, cmd); + } else { /* Use private command */ + memset(&ifr, 0, sizeof(ifr)); + memset(&priv_cmd, 0, sizeof(priv_cmd)); + os_memcpy(buf, cmd, strlen(cmd) + 1); + os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ); + + priv_cmd.buf = buf; + priv_cmd.used_len = buf_len; + priv_cmd.total_len = buf_len; + ifr.ifr_data = &priv_cmd; + + if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) { + wpa_printf(MSG_ERROR, "%s: failed to issue private commands, ret:%d, errno:%d\n", __func__, ret, errno); + } else { + drv_errors = 0; + if((os_strncasecmp(cmd, "SETBAND", 7) == 0) && + ret == DO_NOT_SEND_CHANNEL_CHANGE_EVENT) { + return 0; + } + + ret = 0; + if ((os_strcasecmp(cmd, "LINKSPEED") == 0) || + (os_strcasecmp(cmd, "RSSI") == 0) || + (os_strstr(cmd, "GET") != NULL)) + ret = strlen(buf); + else if (os_strcasecmp(cmd, "P2P_DEV_ADDR") == 0) + wpa_printf(MSG_DEBUG, "%s: P2P: Device address ("MACSTR")", + __func__, MAC2STR(buf)); + else if (os_strcasecmp(cmd, "P2P_SET_PS") == 0) + wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf); + else if (os_strcasecmp(cmd, "P2P_SET_NOA") == 0) + wpa_printf(MSG_DEBUG, "%s: P2P: %s ", __func__, buf); + else if (os_strcasecmp(cmd, "STOP") == 0) { + wpa_printf(MSG_DEBUG, "%s: %s ", __func__, buf); + dl_list_for_each(driver, &drv->global->interfaces, struct wpa_driver_nl80211_data, list) { + linux_set_iface_flags(drv->global->ioctl_sock, driver->first_bss->ifname, 0); + wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); + } + } + else + wpa_printf(MSG_DEBUG, "%s %s len = %d, %zu", __func__, buf, ret, buf_len); + wpa_driver_notify_country_change(drv->ctx, cmd); + } + } + return ret; +} + +int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration) +{ + char buf[MAX_DRV_CMD_SIZE]; + char reply_buf[MAX_DRV_CMD_SIZE]; + + memset(buf, 0, sizeof(buf)); + memset(reply_buf, 0, sizeof(reply_buf)); + wpa_printf(MSG_DEBUG, "%s: Entry", __func__); + snprintf(buf, sizeof(buf), "P2P_SET_NOA %d %d %d", count, start, duration); + return wpa_driver_nl80211_driver_cmd(priv, buf, reply_buf, sizeof(reply_buf)); +} + +int wpa_driver_get_p2p_noa(void *priv, u8 *buf, size_t len) +{ + UNUSED(priv), UNUSED(buf), UNUSED(len); + /* Return 0 till we handle p2p_presence request completely in the driver */ + return 0; +} + +int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow) +{ + char buf[MAX_DRV_CMD_SIZE]; + char reply_buf[MAX_DRV_CMD_SIZE]; + + memset(buf, 0, sizeof(buf)); + memset(reply_buf, 0, sizeof(reply_buf)); + wpa_printf(MSG_DEBUG, "%s: Entry", __func__); + snprintf(buf, sizeof(buf), "P2P_SET_PS %d %d %d", legacy_ps, opp_ps, ctwindow); + return wpa_driver_nl80211_driver_cmd(priv, buf, reply_buf, sizeof(reply_buf)); +} + +int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon, + const struct wpabuf *proberesp, + const struct wpabuf *assocresp) +{ + UNUSED(priv), UNUSED(beacon), UNUSED(proberesp), UNUSED(assocresp); + return 0; +} diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c new file mode 100644 index 0000000..7df7166 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c @@ -0,0 +1,185 @@ +/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + * Changes from Qualcomm Innovation Center are provided under the following license: + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + +#include <netlink/object-api.h> +#include <linux/pkt_sched.h> +#include <dlfcn.h> +#include <dirent.h> +#include <string.h> +#include "common.h" +#include "driver_cmd_nl80211_extn.h" + +#define QCA_NL80211_VENDOR_SUBCMD_DIAG_DATA 201 +#define MAX_OEM_LIBS 5 +#define MAX_LIB_NAME_SIZE 30 +#define CB_SUFFIX "_cb" +static wpa_driver_oem_cb_table_t oem_cb_array[MAX_OEM_LIBS + 1]; + +void wpa_msg_handler(struct wpa_driver_nl80211_data *drv, char *msg, u32 subcmd) { + if (subcmd == QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) { + wpa_msg(drv->ctx, MSG_INFO, "%s", msg); + } +} + +int wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t **oem_cb_table) +{ + wpa_driver_oem_get_cb_table_t *get_oem_table; + wpa_driver_oem_cb_table_t *oem_cb_table_local; + struct dirent *entry; + void *oem_handle_n; + char cb_sym_name[MAX_LIB_NAME_SIZE], *tmp; + DIR *oem_lib_dir; + unsigned int lib_n; +#ifdef ANDROID +#if __WORDSIZE == 64 + char *oem_lib_path = "/vendor/lib64/"; +#else + char *oem_lib_path = "/vendor/lib/"; +#endif +#else + char *oem_lib_path = "/usr/lib/"; +#endif + /* Return the callback table if it is already initialized*/ + if (*oem_cb_table) + return WPA_DRIVER_OEM_STATUS_SUCCESS; + + for (lib_n = 0; lib_n < MAX_OEM_LIBS; lib_n++) { + oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL; + oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event = NULL; + oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb = NULL; + } + + oem_lib_dir = opendir(oem_lib_path); + if (!oem_lib_dir) { + wpa_printf(MSG_ERROR, "%s: Unable to open %s", __FUNCTION__, oem_lib_path); + return WPA_DRIVER_OEM_STATUS_FAILURE; + } + + lib_n = 0; + while((entry = readdir(oem_lib_dir)) != NULL) { + if (strncmp(entry->d_name, "libwpa_drv_oem", 14)) + continue; + + wpa_printf(MSG_DEBUG, "%s: Opening lib %s", __FUNCTION__, entry->d_name); + oem_handle_n = dlopen(entry->d_name, RTLD_NOW); + + if (!oem_handle_n) { + wpa_printf(MSG_ERROR, "%s: Could not load %s", __FUNCTION__, entry->d_name); + /* let's not worry much, continue with others */ + continue; + } + + if (strlen(entry->d_name) >= (sizeof(cb_sym_name) - sizeof(CB_SUFFIX))) { + wpa_printf(MSG_ERROR, "%s: libname (%s) too lengthy", __FUNCTION__, entry->d_name); + continue; + } + + os_strlcpy(cb_sym_name, entry->d_name, sizeof(cb_sym_name)); + tmp = strchr(cb_sym_name, '.'); + if (!tmp) { + wpa_printf(MSG_ERROR, "%s: libname (%s) incorrect?", __FUNCTION__, entry->d_name); + continue; + } + + os_strlcpy(tmp, CB_SUFFIX, sizeof(CB_SUFFIX)); + wpa_printf(MSG_DEBUG, "%s: Loading sym %s", __FUNCTION__, cb_sym_name); + + /* Get the lib's function table callback */ + get_oem_table = (wpa_driver_oem_get_cb_table_t *)dlsym(oem_handle_n, + cb_sym_name); + + if (!get_oem_table) { + wpa_printf(MSG_ERROR, "%s: Could not get sym table", __FUNCTION__); + continue; + } + + oem_cb_table_local = get_oem_table(); + + oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = + oem_cb_table_local->wpa_driver_driver_cmd_oem_cb; + oem_cb_array[lib_n].wpa_driver_nl80211_driver_oem_event = + oem_cb_table_local->wpa_driver_nl80211_driver_oem_event; + oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb = + oem_cb_table_local->wpa_driver_driver_wpa_msg_oem_cb; + oem_cb_array[lib_n].wpa_driver_oem_feature_check_cb = + oem_cb_table_local->wpa_driver_oem_feature_check_cb; + + /* Register wpa message callback with the oem library */ + if(oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb) { + oem_cb_array[lib_n].wpa_driver_driver_wpa_msg_oem_cb(wpa_msg_handler); + } + + lib_n++; + + if (lib_n == MAX_OEM_LIBS) { + wpa_printf(MSG_DEBUG, "%s: Exceeded max libs %d", __FUNCTION__, lib_n); + break; + } + } + + oem_cb_array[lib_n].wpa_driver_driver_cmd_oem_cb = NULL; + *oem_cb_table = oem_cb_array; + wpa_printf(MSG_DEBUG, "%s: OEM lib initialized\n", __func__); + closedir(oem_lib_dir); + + return WPA_DRIVER_OEM_STATUS_SUCCESS; +} diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h new file mode 100755 index 0000000..6246602 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h @@ -0,0 +1,99 @@ +/* Copyright (c) 2016, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + * + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) 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 Qualcomm Innovation Center, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. 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 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + */ + + +#ifndef __DRIVER_CMD_NL80211_EXTN__ +#define __DRIVER_CMD_NL80211_EXTN__ + +#include "qca-vendor_copy.h" +#include <stdbool.h> +#include <sys/types.h> +#include "driver_nl80211.h" + + +#define IFNAMSIZ 16 + +enum wpa_driver_oem_status { + WPA_DRIVER_OEM_STATUS_SUCCESS = 0, + WPA_DRIVER_OEM_STATUS_FAILURE = -1, + WPA_DRIVER_OEM_STATUS_ENOSUPP = -2, +}; + +#define FEATURE_TWT_SUPPORT 0x0001 + +/* + * This structure is a table of function pointers to the functions + * used by the wpa_supplicant_lib to interface with oem specific APIs + */ +typedef struct +{ + int (*wpa_driver_driver_cmd_oem_cb)(void *priv, + char *cmd, char *buf, size_t buf_len, int *status); + int (*wpa_driver_nl80211_driver_oem_event)(struct wpa_driver_nl80211_data *drv, + u32 vendor_id, u32 subcmd, u8 *data, size_t len); + void (*wpa_driver_driver_wpa_msg_oem_cb)(void(*)(struct wpa_driver_nl80211_data *drv, + char *msg, u32 subcmd)); + int (*wpa_driver_oem_feature_check_cb)(u32 feature); +} wpa_driver_oem_cb_table_t; + +typedef wpa_driver_oem_cb_table_t* (wpa_driver_oem_get_cb_table_t)(); + +int wpa_driver_oem_initialize(wpa_driver_oem_cb_table_t **oem_lib_params); +#endif diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h new file mode 100644 index 0000000..40b0cd4 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h @@ -0,0 +1,12055 @@ +/* + * Qualcomm Atheros OUI and vendor specific assignments + * Copyright (c) 2014-2017, Qualcomm Atheros, Inc. + * Copyright (c) 2018-2021, The Linux Foundation + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef QCA_VENDOR_H +#define QCA_VENDOR_H + +/* + * This file is a registry of identifier assignments from the Qualcomm Atheros + * OUI 00:13:74 for purposes other than MAC address assignment. New identifiers + * can be assigned through normal review process for changes to the upstream + * hostap.git repository. + */ + +#define OUI_QCA 0x001374 + +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + +/** + * enum qca_radiotap_vendor_ids - QCA radiotap vendor namespace IDs + */ +enum qca_radiotap_vendor_ids { + QCA_RADIOTAP_VID_WLANTEST = 0, +}; + +/** + * enum qca_nl80211_vendor_subcmds - QCA nl80211 vendor command identifiers + * + * @QCA_NL80211_VENDOR_SUBCMD_UNSPEC: Reserved value 0 + * + * @QCA_NL80211_VENDOR_SUBCMD_TEST: Test command/event + * + * @QCA_NL80211_VENDOR_SUBCMD_ROAMING: Set roaming policy for drivers that use + * internal BSS-selection. This command uses + * @QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY to specify the new roaming policy + * for the current connection (i.e., changes policy set by the nl80211 + * Connect command). @QCA_WLAN_VENDOR_ATTR_MAC_ADDR may optionally be + * included to indicate which BSS to use in case roaming is disabled. + * + * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY: Recommendation of frequency + * ranges to avoid to reduce issues due to interference or internal + * co-existence information in the driver. These frequencies aim to + * minimize the traffic but not to totally avoid the traffic. That said + * for a P2P use case, these frequencies are allowed for the P2P + * discovery/negotiation but avoid the group to get formed on these + * frequencies. The event data structure is defined in + * struct qca_avoid_freq_list. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY: Command to check driver support + * for DFS offloading. + * + * @QCA_NL80211_VENDOR_SUBCMD_NAN: NAN command/event which is used to pass + * NAN Request/Response and NAN Indication messages. These messages are + * interpreted between the framework and the firmware component. While + * sending the command from userspace to the driver, payload is not + * encapsulated inside any attribute. Attribute QCA_WLAN_VENDOR_ATTR_NAN + * is used when receiving vendor events in userspace from the driver. + * + * @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY: Set key operation that can be + * used to configure PMK to the driver even when not connected. This can + * be used to request offloading of key management operations. Only used + * if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD. + * + * @QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH: An extended version of + * NL80211_CMD_ROAM event with optional attributes including information + * from offloaded key management operation. Uses + * enum qca_wlan_vendor_attr_roam_auth attributes. Only used + * if device supports QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD. + * + * @QCA_NL80211_VENDOR_SUBCMD_DO_ACS: ACS command/event which is used to + * invoke the ACS function in device and pass selected channels to + * hostapd. Uses enum qca_wlan_vendor_attr_acs_offload attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Command to get the features + * supported by the driver. enum qca_wlan_vendor_features defines + * the possible features. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Event used by driver, + * which supports DFS offloading, to indicate a channel availability check + * start. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED: Event used by driver, + * which supports DFS offloading, to indicate a channel availability check + * completion. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED: Event used by driver, + * which supports DFS offloading, to indicate that the channel availability + * check aborted, no change to the channel status. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED: Event used by + * driver, which supports DFS offloading, to indicate that the + * Non-Occupancy Period for this channel is over, channel becomes usable. + * + * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED: Event used by driver, + * which supports DFS offloading, to indicate a radar pattern has been + * detected. The channel is now unusable. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO: Get information from the driver. + * Attributes defined in enum qca_wlan_vendor_attr_get_wifi_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET: Get the feature bitmap + * based on enum wifi_logger_supported_features. Attributes defined in + * enum qca_wlan_vendor_attr_get_logger_features. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA: Get the ring data from a particular + * logger ring, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID is passed as the + * attribute for this command. Attributes defined in + * enum qca_wlan_vendor_attr_wifi_logger_start. + * + * @QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES: Get the supported TDLS + * capabilities of the driver, parameters includes the attributes defined + * in enum qca_wlan_vendor_attr_tdls_get_capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS: Vendor command used to offload + * sending of certain periodic IP packet to firmware, attributes defined in + * enum qca_wlan_vendor_attr_offloaded_packets. + * + * @QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI: Command used to configure RSSI + * monitoring, defines min and max RSSI which are configured for RSSI + * monitoring. Also used to notify the RSSI breach and provides the BSSID + * and RSSI value that was breached. Attributes defined in + * enum qca_wlan_vendor_attr_rssi_monitoring. + * + * @QCA_NL80211_VENDOR_SUBCMD_NDP: Command used for performing various NAN + * Data Path (NDP) related operations, attributes defined in + * enum qca_wlan_vendor_attr_ndp_params. + * + * @QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD: Command used to enable/disable + * Neighbour Discovery offload, attributes defined in + * enum qca_wlan_vendor_attr_nd_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER: Used to set/get the various + * configuration parameter for BPF packet filter, attributes defined in + * enum qca_wlan_vendor_attr_packet_filter. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE: Gets the driver-firmware + * maximum supported size, attributes defined in + * enum qca_wlan_vendor_drv_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS: Command to get various + * data about wake reasons and datapath IP statistics, attributes defined + * in enum qca_wlan_vendor_attr_wake_stats. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG: Command used to set configuration + * for IEEE 802.11 communicating outside the context of a basic service + * set, called OCB command. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_set_config. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME: Command used to set OCB + * UTC time. Use the attributes defines in + * enum qca_wlan_vendor_attr_ocb_set_utc_time. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT: Command used to start + * sending OCB timing advert frames. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_start_timing_advert. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT: Command used to stop + * OCB timing advert. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_stop_timing_advert. + * + * @QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER: Command used to get TSF + * timer value. Uses the attributes defines in + * enum qca_wlan_vendor_attr_ocb_get_tsf_resp. + * + * @QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES: Command/event to update the + * link properties of the respective interface. As an event, is used + * to notify the connected station's status. The attributes for this + * command are defined in enum qca_wlan_vendor_attr_link_properties. + * + * @QCA_NL80211_VENDOR_SUBCMD_SETBAND: Command to configure the enabled band(s) + * to the driver. This command sets the band(s) through either the + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE or + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK (or both). + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE refers enum qca_set_band as unsigned + * integer values and QCA_WLAN_VENDOR_ATTR_SETBAND_MASK refers it as 32 + * bit unsigned bitmask values. The allowed values for + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE are limited to QCA_SETBAND_AUTO, + * QCA_SETBAND_5G, and QCA_SETBAND_2G. Other values/bitmasks are valid for + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. The attribute + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE is deprecated and the recommendation + * is to use the QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. If the both attributes + * are included for backwards compatibility, the configurations through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK will take the precedence with drivers + * that support both attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY: This command is used to configure + * DFS policy and channel hint for ACS operation. This command uses the + * attributes defined in enum qca_wlan_vendor_attr_acs_config and + * enum qca_acs_dfs_mode. + * + * @QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START: Command used to + * start the P2P Listen offload function in device and pass the listen + * channel, period, interval, count, device types, and vendor specific + * information elements to the device driver and firmware. + * Uses the attributes defines in + * enum qca_wlan_vendor_attr_p2p_listen_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP: Command/event used to + * indicate stop request/response of the P2P Listen offload function in + * device. As an event, it indicates either the feature stopped after it + * was already running or feature has actually failed to start. Uses the + * attributes defines in enum qca_wlan_vendor_attr_p2p_listen_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH: After AP starts + * beaconing, this sub command provides the driver, the frequencies on the + * 5 GHz band to check for any radar activity. Driver selects one channel + * from this priority list provided through + * @QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST and starts + * to check for radar activity on it. If no radar activity is detected + * during the channel availability check period, driver internally switches + * to the selected frequency of operation. If the frequency is zero, driver + * internally selects a channel. The status of this conditional switch is + * indicated through an event using the same sub command through + * @QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS. Attributes are + * listed in qca_wlan_vendor_attr_sap_conditional_chan_switch. + * + * @QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND: Set GPIO pins. This uses the + * attributes defined in enum qca_wlan_gpio_attr. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY: Fetch hardware capabilities. + * This uses @QCA_WLAN_VENDOR_ATTR_GET_HW_CAPABILITY to indicate which + * capabilities are to be fetched and other + * enum qca_wlan_vendor_attr_get_hw_capability attributes to return the + * requested capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT: Link layer statistics extension. + * enum qca_wlan_vendor_attr_ll_stats_ext attributes are used with this + * command and event. + * + * @QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA: Get capabilities for + * indoor location features. Capabilities are reported in + * QCA_WLAN_VENDOR_ATTR_LOC_CAPA. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION: Start an FTM + * (fine timing measurement) session with one or more peers. + * Specify Session cookie in QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE and + * peer information in QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS. + * On success, 0 or more QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT + * events will be reported, followed by + * QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE event to indicate + * end of session. + * Refer to IEEE P802.11-REVmc/D7.0, 11.24.6 + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION: Abort a running session. + * A QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE will be reported with + * status code indicating session was aborted. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT: Event with measurement + * results for one peer. Results are reported in + * QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE: Event triggered when + * FTM session is finished, either successfully or aborted by + * request. + * + * @QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER: Configure FTM responder + * mode. QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE specifies whether + * to enable or disable the responder. LCI/LCR reports can be + * configured with QCA_WLAN_VENDOR_ATTR_FTM_LCI and + * QCA_WLAN_VENDOR_ATTR_FTM_LCR. Can be called multiple + * times to update the LCI/LCR reports. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS: Perform a standalone AOA (angle of + * arrival) measurement with a single peer. Specify peer MAC address in + * QCA_WLAN_VENDOR_ATTR_MAC_ADDR and optionally frequency (MHz) in + * QCA_WLAN_VENDOR_ATTR_FREQ (if not specified, locate peer in kernel + * scan results cache and use the frequency from there). + * Also specify measurement type in QCA_WLAN_VENDOR_ATTR_AOA_TYPE. + * Measurement result is reported in + * QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT event. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS: Abort an AOA measurement. Specify + * peer MAC address in QCA_WLAN_VENDOR_ATTR_MAC_ADDR. + * + * @QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT: Event that reports + * the AOA measurement result. + * Peer MAC address reported in QCA_WLAN_VENDOR_ATTR_MAC_ADDR. + * success/failure status is reported in + * QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS. + * Measurement data is reported in QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT. + * The antenna array(s) used in the measurement are reported in + * QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK. + * + * @QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST: Encrypt/decrypt the given + * data as per the given parameters. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI: Get antenna RSSI value for a + * specific chain. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG: Get low level + * configuration for a DMG RF sector. Specify sector index in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX, sector type in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and RF modules + * to return sector information for in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_MODULE_MASK. Returns sector configuration + * in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG. Also return the + * exact time where information was captured in + * QCA_WLAN_VENDOR_ATTR_TSF. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG: Set low level + * configuration for a DMG RF sector. Specify sector index in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX, sector type in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and sector configuration + * for one or more DMG RF modules in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR: Get selected + * DMG RF sector for a station. This is the sector that the HW + * will use to communicate with the station. Specify the MAC address + * of associated station/AP/PCP in QCA_WLAN_VENDOR_ATTR_MAC_ADDR (not + * needed for unassociated station). Specify sector type to return in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE. Returns the selected + * sector index in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX. + * Also return the exact time where the information was captured + * in QCA_WLAN_VENDOR_ATTR_TSF. + * + * @QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR: Set the + * selected DMG RF sector for a station. This is the sector that + * the HW will use to communicate with the station. + * Specify the MAC address of associated station/AP/PCP in + * QCA_WLAN_VENDOR_ATTR_MAC_ADDR, the sector type to select in + * QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE and the sector index + * in QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX. + * The selected sector will be locked such that it will not be + * modified like it normally does (for example when station + * moves around). To unlock the selected sector for a station + * pass the special value 0xFFFF in the sector index. To unlock + * all connected stations also pass a broadcast MAC address. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS: Configure the TDLS behavior + * in the host driver. The different TDLS configurations are defined + * by the attributes in enum qca_wlan_vendor_attr_tdls_configuration. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES: Query device IEEE 802.11ax HE + * capabilities. The response uses the attributes defined in + * enum qca_wlan_vendor_attr_get_he_capabilities. + * + * @QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN: Abort an ongoing vendor scan that was + * started with QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN. This command + * carries the scan cookie of the corresponding scan request. The scan + * cookie is represented by QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS: Set the Specific + * Absorption Rate (SAR) power limits. A critical regulation for + * FCC compliance, OEMs require methods to set SAR limits on TX + * power of WLAN/WWAN. enum qca_vendor_attr_sar_limits + * attributes are used with this command. + * + * @QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS: This command/event is used by the + * host driver for offloading the implementation of Auto Channel Selection + * (ACS) to an external user space entity. This interface is used as the + * event from the host driver to the user space entity and also as the + * request from the user space entity to the host driver. The event from + * the host driver is used by the user space entity as an indication to + * start the ACS functionality. The attributes used by this event are + * represented by the enum qca_wlan_vendor_attr_external_acs_event. + * User space entity uses the same interface to inform the host driver with + * selected channels after the ACS operation using the attributes defined + * by enum qca_wlan_vendor_attr_external_acs_channels. + * + * @QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE: Vendor event carrying the + * requisite information leading to a power save failure. The information + * carried as part of this event is represented by the + * enum qca_attr_chip_power_save_failure attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET: Start/Stop the NUD statistics + * collection. Uses attributes defined in enum qca_attr_nud_stats_set. + * + * @QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET: Get the NUD statistics. These + * statistics are represented by the enum qca_attr_nud_stats_get + * attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS: Sub-command to fetch + * the BSS transition status, whether accept or reject, for a list of + * candidate BSSIDs provided by the userspace. This uses the vendor + * attributes QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON and + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO. The userspace shall specify + * the attributes QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON and an + * array of QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID nested in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO in the request. In the response + * the driver shall specify array of + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID and + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS pairs nested in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL: Set the trace level for a + * specific QCA module. The trace levels are represented by + * enum qca_attr_trace_level attributes. + * + * @QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT: Set the Beam Refinement + * Protocol antenna limit in different modes. See enum + * qca_wlan_vendor_attr_brp_ant_limit_mode. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START: Start spectral scan. The scan + * parameters are specified by enum qca_wlan_vendor_attr_spectral_scan. + * This returns a cookie (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE) + * identifying the operation in success case. In failure cases an + * error code (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE) + * describing the reason for the failure is returned. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP: Stop spectral scan. This uses + * a cookie (%QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE) from + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START to identify the scan to + * be stopped. + * + * @QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS: Set the active Type Of Service on the + * specific interface. This can be used to modify some of the low level + * scan parameters (off channel dwell time, home channel time) in the + * driver/firmware. These parameters are maintained within the host driver. + * This command is valid only when the interface is in the connected state. + * These scan parameters shall be reset by the driver/firmware once + * disconnected. The attributes used with this command are defined in + * enum qca_wlan_vendor_attr_active_tos. + * + * @QCA_NL80211_VENDOR_SUBCMD_HANG: Event indicating to the user space that the + * driver has detected an internal failure. This event carries the + * information indicating the reason that triggered this detection. The + * attributes for this command are defined in + * enum qca_wlan_vendor_attr_hang. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CONFIG: Get the current values + * of spectral parameters used. The spectral scan parameters are specified + * by enum qca_wlan_vendor_attr_spectral_scan. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS: Get the debug stats + * for spectral scan functionality. The debug stats are specified by + * enum qca_wlan_vendor_attr_spectral_diag_stats. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO: Get spectral + * scan system capabilities. The capabilities are specified + * by enum qca_wlan_vendor_attr_spectral_cap. + * + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS: Get the current + * status of spectral scan. The status values are specified + * by enum qca_wlan_vendor_attr_spectral_scan_status. + * + * @QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING: Sub-command to flush + * peer pending packets. Specify the peer MAC address in + * QCA_WLAN_VENDOR_ATTR_PEER_ADDR and the access category of the packets + * in QCA_WLAN_VENDOR_ATTR_AC. The attributes are listed + * in enum qca_wlan_vendor_attr_flush_pending. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO: Get vendor specific Representative + * RF Operating Parameter (RROP) information. The attributes for this + * information are defined in enum qca_wlan_vendor_attr_rrop_info. This is + * intended for use by external Auto Channel Selection applications. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS: Get the Specific Absorption Rate + * (SAR) power limits. This is a companion to the command + * @QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS and is used to retrieve the + * settings currently in use. The attributes returned by this command are + * defined by enum qca_vendor_attr_sar_limits. + * + * @QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO: Provides the current behavior of + * the WLAN hardware MAC. Also, provides the WLAN netdev interface + * information attached to the respective MAC. + * This works both as a query (user space asks the current mode) or event + * interface (driver advertising the current mode to the user space). + * Driver does not trigger this event for temporary hardware mode changes. + * Mode changes w.r.t Wi-Fi connection update (VIZ creation / deletion, + * channel change, etc.) are updated with this event. Attributes for this + * interface are defined in enum qca_wlan_vendor_attr_mac. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH: Set MSDU queue depth threshold + * per peer per TID. Attributes for this command are define in + * enum qca_wlan_set_qdepth_thresh_attr. + * @QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD: Provides the thermal shutdown action + * guide for WLAN driver. Request to suspend of driver and FW if the + * temperature is higher than the suspend threshold; resume action is + * requested to driver if the temperature is lower than the resume + * threshold. In user poll mode, request temperature data by user. For test + * purpose, getting thermal shutdown configuration parameters is needed. + * Attributes for this interface are defined in + * enum qca_wlan_vendor_attr_thermal_cmd. + * @QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT: Thermal events reported from + * driver. Thermal temperature and indication of resume completion are + * reported as thermal events. The attributes for this command are defined + * in enum qca_wlan_vendor_attr_thermal_event. + * + * @QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION: Sub command to set WiFi + * test configuration. Attributes for this command are defined in + * enum qca_wlan_vendor_attr_wifi_test_config. + * + * @QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER: This command is used to configure an + * RX filter to receive frames from stations that are active on the + * operating channel, but not associated with the local device (e.g., STAs + * associated with other APs). Filtering is done based on a list of BSSIDs + * and STA MAC addresses added by the user. This command is also used to + * fetch the statistics of unassociated stations. The attributes used with + * this command are defined in enum qca_wlan_vendor_attr_bss_filter. + * + * @QCA_NL80211_VENDOR_SUBCMD_NAN_EXT: An extendable version of NAN vendor + * command. The earlier command for NAN, QCA_NL80211_VENDOR_SUBCMD_NAN, + * carried a payload which was a binary blob of data. The command was not + * extendable to send more information. The newer version carries the + * legacy blob encapsulated within an attribute and can be extended with + * additional vendor attributes that can enhance the NAN command interface. + * @QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT: Event to indicate scan triggered + * or stopped within driver/firmware in order to initiate roaming. The + * attributes used with this event are defined in enum + * qca_wlan_vendor_attr_roam_scan. Some drivers may not send these events + * in few cases, e.g., if the host processor is sleeping when this event + * is generated in firmware. + * + * @QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG: This command is used to + * configure parameters per peer to capture Channel Frequency Response + * (CFR) and enable Periodic CFR capture. The attributes for this command + * are defined in enum qca_wlan_vendor_peer_cfr_capture_attr. This command + * can also be used to send CFR data from the driver to userspace when + * netlink events are used to send CFR data. + * + * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes + * in throughput dynamically. The driver estimates the throughput based on + * number of packets being transmitted/received per second and indicates + * the changes in throughput to user space. Userspace tools can use this + * information to configure kernel's TCP parameters in order to achieve + * peak throughput. Optionally, the driver will also send guidance on + * modifications to kernel's TCP parameters which can be referred by + * userspace tools. The attributes used with this event are defined in enum + * qca_wlan_vendor_attr_throughput_change. + * + * @QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG: This command is used to set + * priorities among different types of traffic during coex scenarios. + * Current supported prioritization is among WLAN/BT/ZIGBEE with different + * profiles mentioned in enum qca_coex_config_profiles. The associated + * attributes used with this command are defined in enum + * qca_vendor_attr_coex_config. + * + * Based on the config provided, FW will boost the weight and prioritize + * the traffic for that subsystem (WLAN/BT/Zigbee). + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS: This command is used to query + * the supported AKM suite selectorss from the driver. It returns the list + * of supported AKMs in the attribute NL80211_ATTR_AKM_SUITES. + * @QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE: This command is used to get firmware + * state from the driver. It returns the firmware state in the attribute + * QCA_WLAN_VENDOR_ATTR_FW_STATE. + * @QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH: This vendor subcommand + * is used by the driver to flush per-peer cached statistics to user space + * application. This interface is used as an event from the driver to + * user space application. Attributes for this event are specified in + * enum qca_wlan_vendor_attr_peer_stats_cache_params. + * QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA attribute is expected to be + * sent in the event. + * @QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG: This sub command is used to + * improve the success rate of Zigbee joining network. + * Due to PTA master limitation, Zigbee joining network success rate is + * low while WLAN is working. The WLAN driver needs to configure some + * parameters including Zigbee state and specific WLAN periods to enhance + * PTA master. All these parameters are delivered by the attributes + * defined in enum qca_mpta_helper_vendor_attr. + * @QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING: This sub command is used to + * implement Beacon frame reporting feature. + * + * Userspace can request the driver/firmware to periodically report + * received Beacon frames whose BSSID is same as the current connected + * BSS's MAC address. + * + * In case the STA seamlessly (without sending disconnect indication to + * userspace) roams to a different BSS, Beacon frame reporting will be + * automatically enabled for the Beacon frames whose BSSID is same as the + * MAC address of the new BSS. Beacon reporting will be stopped when the + * STA is disconnected (when the disconnect indication is sent to + * userspace) and need to be explicitly enabled by userspace for next + * connection. + * + * When a Beacon frame matching configured conditions is received, and if + * userspace has requested to send asynchronous beacon reports, the + * driver/firmware will encapsulate the details of the Beacon frame in an + * event and send it to userspace along with updating the BSS information + * in cfg80211 scan cache, otherwise driver will only update the cfg80211 + * scan cache with the information from the received Beacon frame but will + * not send any active report to userspace. + * + * The userspace can request the driver/firmware to stop reporting Beacon + * frames. If the driver/firmware is not able to receive Beacon frames due + * to other Wi-Fi operations such as off-channel activities, etc., the + * driver/firmware will send a pause event to userspace and stop reporting + * Beacon frames. Whether the beacon reporting will be automatically + * resumed or not by the driver/firmware later will be reported to + * userspace using the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES + * flag. The beacon reporting shall be resumed for all the cases except + * either when userspace sets + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_DO_NOT_RESUME flag in the command + * which triggered the current beacon reporting or during any disconnection + * case as indicated by setting + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON to + * QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED by the + * driver. + * + * After QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_PAUSE event is received + * by userspace with QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES + * flag not set, the next first + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO event from the driver + * shall be considered as un-pause event. + * + * All the attributes used with this command are defined in + * enum qca_wlan_vendor_attr_beacon_reporting_params. + * @QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP: In practice, some APs have + * interop issues with the DUT. This sub command is used to transfer the + * AP info between the driver and user space. This works both as a command + * and an event. As a command, it configures the stored list of APs from + * user space to firmware; as an event, it indicates the AP info detected + * by the firmware to user space for persistent storage. The attributes + * defined in enum qca_vendor_attr_interop_issues_ap are used to deliver + * the parameters. + * @QCA_NL80211_VENDOR_SUBCMD_OEM_DATA: This command/event is used to + * send/receive OEM data binary blobs to/from application/service to/from + * firmware. The attributes defined in enum + * qca_wlan_vendor_attr_oem_data_params are used to deliver the + * parameters. + * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT: This command/event is used + * to send/receive avoid frequency data using + * enum qca_wlan_vendor_attr_avoid_frequency_ext. + * This new command is alternative to existing command + * QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY since existing command/event + * is using stream of bytes instead of structured data using vendor + * attributes. User space sends unsafe frequency ranges to the driver using + * a nested attribute %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE. On + * reception of this command, the driver shall check if an interface is + * operating on an unsafe frequency and the driver shall try to move to a + * safe channel when needed. If the driver is not able to find a safe + * channel the interface can keep operating on an unsafe channel with the + * TX power limit derived based on internal configurations like + * regulatory/SAR rules. + * + * @QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE: This vendor subcommand is used to + * add the STA node details in driver/firmware. Attributes for this event + * are specified in enum qca_wlan_vendor_attr_add_sta_node_params. + * @QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE: This command is used to set BT + * coex chain mode from application/service. + * The attributes defined in enum qca_vendor_attr_btc_chain_mode are used + * to deliver the parameters. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO: This vendor subcommand is used to + * get information of a station from driver to userspace. This command can + * be used in both STA and AP modes. For STA mode, it provides information + * of the current association when in connected state or the last + * association when in disconnected state. For AP mode, only information + * of the currently connected stations is available. This command uses + * attributes defined in enum qca_wlan_vendor_attr_get_sta_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_REQUEST_SAR_LIMITS_EVENT: This acts as an event. + * Host drivers can request the user space entity to set the SAR power + * limits with this event. Accordingly, the user space entity is expected + * to set the SAR power limits. Host drivers can retry this event to the + * user space for the SAR power limits configuration from user space. If + * the driver does not get the SAR power limits from user space for all + * the retried attempts, it can configure a default SAR power limit. + * + * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO: This acts as a vendor event and + * is used to update the information about the station from the driver to + * userspace. Uses attributes from enum + * qca_wlan_vendor_attr_update_sta_info. + * + * @QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON: This acts as an event. + * The host driver initiates the disconnection for scenarios such as beacon + * miss, NUD failure, peer kick out, etc. The disconnection indication + * through cfg80211_disconnected() expects the reason codes from enum + * ieee80211_reasoncode which does not signify these various reasons why + * the driver has triggered the disconnection. This event will be used to + * send the driver specific reason codes by the host driver to userspace. + * Host drivers should trigger this event and pass the respective reason + * code immediately prior to triggering cfg80211_disconnected(). The + * attributes used with this event are defined in enum + * qca_wlan_vendor_attr_driver_disconnect_reason. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC: This vendor subcommand is used to + * add/delete TSPEC for each AC. One command is for one specific AC only. + * This command can only be used in STA mode and the STA must be + * associated with an AP when the command is issued. Uses attributes + * defined in enum qca_wlan_vendor_attr_config_tspec. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT: Vendor subcommand to configure TWT. + * Uses attributes defined in enum qca_wlan_vendor_attr_config_twt. + * + * @QCA_NL80211_VENDOR_SUBCMD_GETBAND: Command to get the enabled band(s) from + * the driver. The band configurations obtained are referred through + * QCA_WLAN_VENDOR_ATTR_SETBAND_MASK. + * + * @QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS: Vendor subcommand/event for medium + * assessment. + * Uses attributes defined in enum qca_wlan_vendor_attr_medium_assess. + * + * @QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID: This acts as a vendor event and is + * used to update SSID information in hostapd when it is updated in the + * driver. Uses the attribute NL80211_ATTR_SSID. + * + * @QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS: This vendor subcommand is used by + * the driver to send opaque data from the firmware to userspace. The + * driver sends an event to userspace whenever such data is received from + * the firmware. + * + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA is used as the attribute to + * send this opaque data for this event. + * + * The format of the opaque data is specific to the particular firmware + * version and there is no guarantee of the format remaining same. + * + * @QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS: This acts as an event. + * The host driver selects Tx VDEV, and notifies user. The attributes + * used with this event are defined in enum + * qca_wlan_vendor_attr_mbssid_tx_vdev_status. + * This event contains Tx VDEV group information, other VDEVs + * interface index, and status information. + * + * @QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY: Vendor command to + * configure the concurrent session policies when multiple STA interfaces + * are (getting) active. The attributes used by this command are defined + * in enum qca_wlan_vendor_attr_concurrent_sta_policy. + * + * @QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS: Userspace can use this command + * to query usable channels for different interface types such as STA, + * AP, P2P GO, P2P Client, NAN, etc. The driver shall report all usable + * channels in the response based on country code, different static + * configurations, concurrency combinations, etc. The attributes used + * with this command are defined in + * enum qca_wlan_vendor_attr_usable_channels. + * + * @QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY: This vendor subcommand is used + * to get DFS radar history from the driver to userspace. The driver + * returns QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES attribute with an + * array of nested entries. + * + * @QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD: Userspace can use this command to + * enable/disable mDNS offload to the firmware. The attributes used with + * this command are defined in enum qca_wlan_vendor_attr_mdns_offload. + * + * @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used + * to set packet monitor mode that aims to send the specified set of TX and + * RX frames on the current client interface to an active monitor + * interface. If this monitor mode is set, the driver will send the + * configured frames, from the interface on which the command is issued, to + * an active monitor interface. The attributes used with this command are + * defined in enum qca_wlan_vendor_attr_set_monitor_mode. + * + * Though the monitor mode is configured for the respective + * Data/Management/Control frames, it is up to the respective WLAN + * driver/firmware/hardware designs to consider the possibility of sending + * these frames over the monitor interface. For example, the Control frames + * are handled within the hardware and thus passing such frames over the + * monitor interface is left to the respective designs. + * + * Also, this monitor mode is governed to behave accordingly in + * suspend/resume states. If the firmware handles any of such frames in + * suspend state without waking up the host and if the monitor mode is + * configured to notify all such frames, the firmware is expected to resume + * the host and forward the respective frames to the monitor interface. + * Please note that such a request to get the frames over the monitor + * interface will have a definite power implication. + * + * @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both + * as a request to set the driver/firmware with the parameters to trigger + * the roaming events, and also used by the driver/firmware to pass on the + * various roam events to userspace. + * Applicable only for the STA mode. The attributes used with this command + * are defined in enum qca_wlan_vendor_attr_roam_events. + * + * @QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG: Subcommand to set or reset the + * rate mask config for a list of PHY types. Userspace shall provide an + * array of the vendor attributes defined in + * enum qca_wlan_vendor_attr_ratemask_params. + * + * @QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA: Multi-channel Concurrency (MCC) occurs + * when two interfaces are active on the same band, using two different + * home channels, and only supported by a single radio. In this scenario + * the device must split the use of the radio between the two interfaces. + * The percentage of time allocated to a given interface is the quota. + * Depending on the configuration, the quota can either be fixed or + * dynamic. + * + * When used as an event, the device will report the quota type, and for + * all interfaces operating in MCC it will report the current quota. + * When used as a command, the device can be configured for a specific + * quota type, and in the case of a fixed quota, the quota to apply to one + * of the interfaces. + * + * Applications can use the event to do TX bitrate control based on the + * information, and can use the command to explicitly set the quota to + * enhance performance in specific scenarios. + * + * The attributes used with this command are defined in + * enum qca_wlan_vendor_attr_mcc_quota. + */ +enum qca_nl80211_vendor_subcmds { + QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0, + QCA_NL80211_VENDOR_SUBCMD_TEST = 1, + /* subcmds 2..8 not yet allocated */ + QCA_NL80211_VENDOR_SUBCMD_ROAMING = 9, + 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, + 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, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_START = 20, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_STOP = 21, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS = 22, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CAPABILITIES = 23, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS = 24, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE = 25, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT = 26, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT = 27, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND = 28, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_BSSID_HOTLIST = 29, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_BSSID_HOTLIST = 30, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE = 31, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SIGNIFICANT_CHANGE = 32, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SIGNIFICANT_CHANGE = 33, + 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, + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES = 38, + QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI = 39, + QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG = 40, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_LOST = 41, + QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX = 42, + /* 43..49 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY = 50, + QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH = 51, + QCA_NL80211_VENDOR_SUBCMD_APFIND = 52, + /* 53 - reserved - was used by QCA, but not in use anymore */ + QCA_NL80211_VENDOR_SUBCMD_DO_ACS = 54, + QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES = 55, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED = 56, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED = 57, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED = 58, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED = 59, + QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED = 60, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO = 61, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START = 62, + QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP = 63, + QCA_NL80211_VENDOR_SUBCMD_ROAM = 64, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST = 65, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_RESET_SSID_HOTLIST = 66, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_FOUND = 67, + QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_SSID_LOST = 68, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST = 69, + QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST = 70, + QCA_NL80211_VENDOR_SUBCMD_PNO_RESET_PASSPOINT_LIST = 71, + QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND = 72, + QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND = 73, + /* Wi-Fi configuration subcommands */ + QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION = 74, + QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION = 75, + QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET = 76, + QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA = 77, + QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES = 78, + QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS = 79, + QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI = 80, + QCA_NL80211_VENDOR_SUBCMD_NDP = 81, + QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD = 82, + QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER = 83, + QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE = 84, + QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS = 85, + /* 86-90 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_DATA_OFFLOAD = 91, + QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG = 92, + QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME = 93, + QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT = 94, + QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT = 95, + QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER = 96, + QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS = 97, + QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS = 98, + QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL = 99, + QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT = 100, + QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101, + QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG = 102, + QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST = 103, + QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL = 104, + QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105, + QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN = 106, + QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE = 107, + QCA_NL80211_VENDOR_SUBCMD_OTA_TEST = 108, + QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE = 109, + /* 110..114 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_DECR_DB = 115, + QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116, + /* 117 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG = 118, + QCA_NL80211_VENDOR_SUBCMD_TSF = 119, + QCA_NL80211_VENDOR_SUBCMD_WISA = 120, + /* 121 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START = 122, + QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP = 123, + QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH = 124, + QCA_NL80211_VENDOR_SUBCMD_GPIO_CONFIG_COMMAND = 125, + QCA_NL80211_VENDOR_SUBCMD_GET_HW_CAPABILITY = 126, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT = 127, + /* FTM/indoor location subcommands */ + QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA = 128, + QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION = 129, + QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION = 130, + QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT = 131, + QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE = 132, + QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER = 133, + QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS = 134, + QCA_NL80211_VENDOR_SUBCMD_AOA_ABORT_MEAS = 135, + QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT = 136, + QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST = 137, + QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI = 138, + /* DMG low level RF sector operations */ + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG = 139, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG = 140, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SELECTED_SECTOR = 141, + QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR = 142, + QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS = 143, + QCA_NL80211_VENDOR_SUBCMD_GET_HE_CAPABILITIES = 144, + QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN = 145, + QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS = 146, + QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS = 147, + QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE = 148, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET = 149, + QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET = 150, + QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS = 151, + QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL = 152, + QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT = 153, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START = 154, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP = 155, + QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS = 156, + QCA_NL80211_VENDOR_SUBCMD_HANG = 157, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CONFIG = 158, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS = 159, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO = 160, + QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS = 161, + /* Flush peer pending data */ + QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING = 162, + QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO = 163, + QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS = 164, + QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO = 165, + QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH = 166, + /* Thermal shutdown commands to protect wifi chip */ + QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD = 167, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT = 168, + /* Wi-Fi test configuration subcommand */ + QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION = 169, + /* Frame filter operations for other BSSs/unassociated STAs */ + QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER = 170, + QCA_NL80211_VENDOR_SUBCMD_NAN_EXT = 171, + QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT = 172, + QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG = 173, + QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT = 174, + QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG = 175, + QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS = 176, + QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE = 177, + QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH = 178, + QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG = 179, + QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING = 180, + QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP = 181, + QCA_NL80211_VENDOR_SUBCMD_OEM_DATA = 182, + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT = 183, + QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE = 184, + QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE = 185, + QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO = 186, + QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS_EVENT = 187, + QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO = 188, + QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON = 189, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC = 190, + QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT = 191, + QCA_NL80211_VENDOR_SUBCMD_GETBAND = 192, + QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS = 193, + QCA_NL80211_VENDOR_SUBCMD_UPDATE_SSID = 194, + QCA_NL80211_VENDOR_SUBCMD_WIFI_FW_STATS = 195, + QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196, + QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197, + QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198, + QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY = 199, + QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD = 200, + /* 201 - reserved for QCA */ + QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202, + QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203, + QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG = 204, + QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA = 205, +}; + +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 only when driver sends vendor events to the userspace under the + * command QCA_NL80211_VENDOR_SUBCMD_NAN. Not used when userspace sends + * commands to the driver. + */ + QCA_WLAN_VENDOR_ATTR_NAN = 2, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, + /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ + QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, + /* used by QCA_NL80211_VENDOR_SUBCMD_ROAMING, u32 with values defined + * by enum qca_roaming_policy. + */ + QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5, + QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6, + /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ + QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7, + QCA_WLAN_VENDOR_ATTR_TEST = 8, + /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA = 9, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND = 10, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND = 11, + /* Unsigned 32-bit value from enum qca_set_band. The allowed values for + * this attribute are limited to QCA_SETBAND_AUTO, QCA_SETBAND_5G, and + * QCA_SETBAND_2G. This attribute is deprecated. Recommendation is to + * use QCA_WLAN_VENDOR_ATTR_SETBAND_MASK instead. + */ + QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE = 12, + /* Dummy (NOP) attribute for 64 bit padding */ + QCA_WLAN_VENDOR_ATTR_PAD = 13, + /* Unique FTM session cookie (Unsigned 64 bit). Specified in + * QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION. Reported in + * the session in QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT and + * QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE. + */ + QCA_WLAN_VENDOR_ATTR_FTM_SESSION_COOKIE = 14, + /* Indoor location capabilities, returned by + * QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA. + * see enum qca_wlan_vendor_attr_loc_capa. + */ + QCA_WLAN_VENDOR_ATTR_LOC_CAPA = 15, + /* Array of nested attributes containing information about each peer + * in FTM measurement session. See enum qca_wlan_vendor_attr_peer_info + * for supported attributes for each peer. + */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEERS = 16, + /* Array of nested attributes containing measurement results for + * one or more peers, reported by the + * QCA_NL80211_VENDOR_SUBCMD_FTM_MEAS_RESULT event. + * See enum qca_wlan_vendor_attr_peer_result for list of supported + * attributes. + */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PEER_RESULTS = 17, + /* Flag attribute for enabling or disabling responder functionality. */ + QCA_WLAN_VENDOR_ATTR_FTM_RESPONDER_ENABLE = 18, + /* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * command to specify the LCI report that will be sent by + * the responder during a measurement exchange. The format is + * defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.10. + */ + QCA_WLAN_VENDOR_ATTR_FTM_LCI = 19, + /* Used in the QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * command to specify the location civic report that will + * be sent by the responder during a measurement exchange. + * The format is defined in IEEE P802.11-REVmc/D7.0, 9.4.2.22.13. + */ + QCA_WLAN_VENDOR_ATTR_FTM_LCR = 20, + /* Session/measurement completion status code, + * reported in QCA_NL80211_VENDOR_SUBCMD_FTM_SESSION_DONE and + * QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT + * see enum qca_vendor_attr_loc_session_status. + */ + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS = 21, + /* Initial dialog token used by responder (0 if not specified), + * unsigned 8 bit value. + */ + QCA_WLAN_VENDOR_ATTR_FTM_INITIAL_TOKEN = 22, + /* AOA measurement type. Requested in QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS + * and optionally in QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION if + * AOA measurements are needed as part of an FTM session. + * Reported by QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT. See + * enum qca_wlan_vendor_attr_aoa_type. + */ + QCA_WLAN_VENDOR_ATTR_AOA_TYPE = 23, + /* A bit mask (unsigned 32 bit value) of antenna arrays used + * by indoor location measurements. Refers to the antenna + * arrays described by QCA_VENDOR_ATTR_LOC_CAPA_ANTENNA_ARRAYS. + */ + QCA_WLAN_VENDOR_ATTR_LOC_ANTENNA_ARRAY_MASK = 24, + /* AOA measurement data. Its contents depends on the AOA measurement + * type and antenna array mask: + * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: array of U16 values, + * phase of the strongest CIR path for each antenna in the measured + * array(s). + * QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: array of 2 U16 + * values, phase and amplitude of the strongest CIR path for each + * antenna in the measured array(s). + */ + QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT = 25, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to specify the chain number (unsigned 32 bit value) to inquire + * the corresponding antenna RSSI value + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_INDEX = 26, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to report the specific antenna RSSI value (unsigned 32 bit value) + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI = 27, + /* Frequency in MHz, various uses. Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_FREQ = 28, + /* TSF timer value, unsigned 64 bit value. + * May be returned by various commands. + */ + QCA_WLAN_VENDOR_ATTR_TSF = 29, + /* DMG RF sector index, unsigned 16 bit number. Valid values are + * 0..127 for sector indices or 65535 as special value used to + * unlock sector selection in + * QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SELECTED_SECTOR. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_INDEX = 30, + /* DMG RF sector type, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_attr_dmg_rf_sector_type. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE = 31, + /* Bitmask of DMG RF modules for which information is requested. Each + * bit corresponds to an RF module with the same index as the bit + * number. Unsigned 32 bit number but only low 8 bits can be set since + * all DMG chips currently have up to 8 RF modules. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_MODULE_MASK = 32, + /* Array of nested attributes where each entry is DMG RF sector + * configuration for a single RF module. + * Attributes for each entry are taken from enum + * qca_wlan_vendor_attr_dmg_rf_sector_cfg. + * Specified in QCA_NL80211_VENDOR_SUBCMD_DMG_RF_SET_SECTOR_CFG + * and returned by QCA_NL80211_VENDOR_SUBCMD_DMG_RF_GET_SECTOR_CFG. + */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG = 33, + /* Used in QCA_NL80211_VENDOR_SUBCMD_STATS_EXT command + * to report frame aggregation statistics to userspace. + */ + QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_NUM = 34, + QCA_WLAN_VENDOR_ATTR_RX_AGGREGATION_STATS_HOLES_INFO = 35, + /* Unsigned 8-bit value representing MBO transition reason code as + * provided by the AP used by subcommand + * QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS. This is + * specified by the userspace in the request to the driver. + */ + QCA_WLAN_VENDOR_ATTR_BTM_MBO_TRANSITION_REASON = 36, + /* Array of nested attributes, BSSID and status code, used by subcommand + * QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS, where each + * entry is taken from enum qca_wlan_vendor_attr_btm_candidate_info. + * The userspace space specifies the list/array of candidate BSSIDs in + * the order of preference in the request. The driver specifies the + * status code, for each BSSID in the list, in the response. The + * acceptable candidates are listed in the order preferred by the + * driver. + */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO = 37, + /* Used in QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT command + * See enum qca_wlan_vendor_attr_brp_ant_limit_mode. + */ + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE = 38, + /* Used in QCA_NL80211_VENDOR_SUBCMD_BRP_SET_ANT_LIMIT command + * to define the number of antennas to use for BRP. + * different purpose in each ANT_LIMIT_MODE: + * DISABLE - ignored + * EFFECTIVE - upper limit to number of antennas to be used + * FORCE - exact number of antennas to be used + * unsigned 8 bit value + */ + QCA_WLAN_VENDOR_ATTR_BRP_ANT_NUM_LIMIT = 39, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command + * to report the corresponding antenna index to the chain RSSI value + */ + QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO = 40, + /* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command to report + * the specific antenna EVM value (unsigned 32 bit value). With a + * determinate group of antennas, the driver specifies the EVM value + * for each antenna ID, and application extract them in user space. + */ + QCA_WLAN_VENDOR_ATTR_CHAIN_EVM = 41, + /* + * Used in QCA_NL80211_VENDOR_SUBCMD_GET_FW_STATE command to report + * wlan firmware current state. FW state is an unsigned 8 bit value, + * one of the values in enum qca_wlan_vendor_attr_fw_state. + */ + QCA_WLAN_VENDOR_ATTR_FW_STATE = 42, + + /* Unsigned 32-bitmask value from enum qca_set_band. Substitutes the + * attribute QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE for which only a subset + * of single values from enum qca_set_band are valid. This attribute + * uses bitmask combinations to define the respective allowed band + * combinations and this attributes takes precedence over + * QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE if both attributes are included. + */ + QCA_WLAN_VENDOR_ATTR_SETBAND_MASK = 43, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1, +}; + +enum qca_roaming_policy { + QCA_ROAMING_NOT_ALLOWED, + QCA_ROAMING_ALLOWED_WITHIN_ESS, +}; + +/** + * enum qca_roam_reason - Represents the reason codes for roaming. Used by + * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON. + * + * @QCA_ROAM_REASON_UNKNOWN: Any reason that do not classify under the below + * reasons. + * + * @QCA_ROAM_REASON_PER: Roam triggered when packet error rates (PER) breached + * the configured threshold. + * + * @QCA_ROAM_REASON_BEACON_MISS: Roam triggered due to the continuous configured + * beacon misses from the then connected AP. + * + * @QCA_ROAM_REASON_POOR_RSSI: Roam triggered due to the poor RSSI reported + * by the connected AP. + * + * @QCA_ROAM_REASON_BETTER_RSSI: Roam triggered for finding a BSS with a better + * RSSI than the connected BSS. Here the RSSI of the current BSS is not poor. + * + * @QCA_ROAM_REASON_CONGESTION: Roam triggered considering the connected channel + * or environment being very noisy or congested. + * + * @QCA_ROAM_REASON_USER_TRIGGER: Roam triggered due to an explicit request + * from the user (user space). + * + * @QCA_ROAM_REASON_BTM: Roam triggered due to BTM Request frame received from + * the connected AP. + * + * @QCA_ROAM_REASON_BSS_LOAD: Roam triggered due to the channel utilization + * breaching out the configured threshold. + * + * @QCA_ROAM_REASON_WTC: Roam triggered due to Wireless to Cellular BSS + * transition request. + * + * @QCA_ROAM_REASON_IDLE: Roam triggered when device is suspended, there is no + * data activity with the AP and the current RSSI falls below a certain + * threshold. + * + * @QCA_ROAM_REASON_DISCONNECTION: Roam triggered due to Deauthentication or + * Disassociation frames received from the connected AP. + * + * @QCA_ROAM_REASON_PERIODIC_TIMER: Roam triggered as part of the periodic scan + * that happens when there is no candidate AP found during the poor RSSI scan + * trigger. + * + * @QCA_ROAM_REASON_BACKGROUND_SCAN: Roam triggered based on the scan results + * obtained from an external scan (not aimed at roaming). + * + * @QCA_ROAM_REASON_BT_ACTIVITY: Roam triggered due to Bluetooth connection is + * established when the station is connected in the 2.4 GHz band. + */ +enum qca_roam_reason { + QCA_ROAM_REASON_UNKNOWN, + QCA_ROAM_REASON_PER, + QCA_ROAM_REASON_BEACON_MISS, + QCA_ROAM_REASON_POOR_RSSI, + QCA_ROAM_REASON_BETTER_RSSI, + QCA_ROAM_REASON_CONGESTION, + QCA_ROAM_REASON_USER_TRIGGER, + QCA_ROAM_REASON_BTM, + QCA_ROAM_REASON_BSS_LOAD, + QCA_ROAM_REASON_WTC, + QCA_ROAM_REASON_IDLE, + QCA_ROAM_REASON_DISCONNECTION, + QCA_ROAM_REASON_PERIODIC_TIMER, + QCA_ROAM_REASON_BACKGROUND_SCAN, + QCA_ROAM_REASON_BT_ACTIVITY, +}; + +enum qca_wlan_vendor_attr_roam_auth { + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS, + /* Indicates the status of re-association requested by user space for + * the BSSID specified by QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID. + * Type u16. + * Represents the status code from AP. Use + * %WLAN_STATUS_UNSPECIFIED_FAILURE if the device cannot give you the + * real status code for failures. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_STATUS, + /* This attribute indicates that the old association was maintained when + * a re-association is requested by user space and that re-association + * attempt fails (i.e., cannot connect to the requested BSS, but can + * remain associated with the BSS with which the association was in + * place when being requested to roam). Used along with + * WLAN_VENDOR_ATTR_ROAM_AUTH_STATUS to indicate the current + * re-association status. Type flag. + * This attribute is applicable only for re-association failure cases. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RETAIN_CONNECTION, + /* This attribute specifies the PMK if one was newly generated during + * FILS roaming. This is added to the PMKSA cache and is used in + * subsequent connections with PMKSA caching. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK = 11, + /* This attribute specifies the PMKID used/generated for the current + * FILS roam. This is used in subsequent connections with PMKSA caching. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID = 12, + /* A 16-bit unsigned value specifying the next sequence number to use + * in ERP message in the currently associated realm. This is used in + * doing subsequent ERP based connections in the same realm. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM = 13, + /* A 16-bit unsigned value representing the reasons for the roaming. + * Defined by enum qca_roam_reason. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON = 14, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_p2p_listen_offload { + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INVALID = 0, + /* A 32-bit unsigned value; the P2P listen frequency (MHz); must be one + * of the social channels. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CHANNEL, + /* A 32-bit unsigned value; the P2P listen offload period (ms). + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_PERIOD, + /* A 32-bit unsigned value; the P2P listen interval duration (ms). + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_INTERVAL, + /* A 32-bit unsigned value; number of interval times the firmware needs + * to run the offloaded P2P listen operation before it stops. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_COUNT, + /* An array of arbitrary binary data with one or more 8-byte values. + * The device types include both primary and secondary device types. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_DEVICE_TYPES, + /* An array of unsigned 8-bit characters; vendor information elements. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_VENDOR_IE, + /* A 32-bit unsigned value; a control flag to indicate whether listen + * results need to be flushed to wpa_supplicant. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_CTRL_FLAG, + /* A 8-bit unsigned value; reason code for P2P listen offload stop + * event. + */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_acs_offload - Defines attributes to be used with + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL: Required (u8). + * Used with event to notify the primary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY instead. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL: Required (u8). + * Used with event to notify the secondary channel number selected in ACS + * operation. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL is still used if either of + * the driver or user space application doesn't support 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE: Required (u8). + * (a) Used with command to configure hw_mode from + * enum qca_wlan_vendor_acs_hw_mode for ACS operation. + * (b) Also used with event to notify the hw_mode of selected primary channel + * in ACS operation. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT mode. + * Disable (flag attribute not present) - HT disabled and + * Enable (flag attribute present) - HT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED: Flag attribute. + * Used with command to configure ACS operation for HT40 mode. + * Disable (flag attribute not present) - HT40 disabled and + * Enable (flag attribute present) - HT40 enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for VHT mode. + * Disable (flag attribute not present) - VHT disabled and + * Enable (flag attribute present) - VHT enabled. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH: Optional (u16) with command and + * mandatory with event. + * If specified in command path, ACS operation is configured with the given + * channel width (in MHz). + * In event path, specifies the channel width of the primary channel selected. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure channel list using an array of + * channel numbers (u8). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver mandates use of QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST whereas + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is optional. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 0 center channel number selected in + * ACS operation. The value is the index of the channel center frequency for + * 20 MHz, 40 MHz, and 80 MHz channels. The value is the center frequency index + * of the primary 80 MHz segment for 160 MHz and 80+80 MHz channels. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL: Required (u8). + * Used with event to notify the VHT segment 1 center channel number selected in + * ACS operation. The value is zero for 20 MHz, 40 MHz, and 80 MHz channels. + * The value is the index of the channel center frequency for 160 MHz channels + * and the center frequency index of the secondary 80 MHz segment for 80+80 MHz + * channels. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is deprecated; use + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY instead. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL is still used if either of + * the driver or user space application doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST: Required and type is NLA_UNSPEC. + * Used with command to configure the channel list using an array of channel + * center frequencies in MHz (u32). + * Note: If both the driver and user-space application supports the 6 GHz band, + * the driver first parses the frequency list and if it fails to get a frequency + * list, parses the channel list specified using + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST (considers only 2 GHz and 5 GHz channels in + * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST). + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY: Required (u32). + * Used with event to notify the primary channel center frequency (MHz) selected + * in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY: Required (u32). + * Used with event to notify the secondary channel center frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 0 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY: Required (u32). + * Used with event to notify the VHT segment 1 center channel frequency (MHz) + * selected in ACS operation. + * Note: If the driver supports the 6 GHz band, the event sent from the driver + * includes this attribute along with + * QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED: Flag attribute. + * Used with command to notify the driver of EDMG request for ACS + * operation. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL: Optional (u8). + * Used with event to notify the EDMG channel number selected in ACS + * operation. + * EDMG primary channel is indicated by QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL + * + * @QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP: Optional (u16). + * Used with event to notify the puncture pattern selected in ACS operation. + * Encoding for this attribute will follow the convention used in the Disabled + * Subchannel Bitmap field of the EHT Operation IE. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED: Flag attribute. + * Used with command to configure ACS operation for EHT mode. + * Disable (flag attribute not present) - EHT disabled and + * Enable (flag attribute present) - EHT enabled. + */ +enum qca_wlan_vendor_attr_acs_offload { + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL = 1, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL = 2, + QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE = 3, + QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED = 4, + QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED = 5, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED = 6, + QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH = 7, + QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST = 8, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL = 9, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL = 10, + QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST = 11, + QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_FREQUENCY = 12, + QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_FREQUENCY = 13, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_FREQUENCY = 14, + QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_FREQUENCY = 15, + QCA_WLAN_VENDOR_ATTR_ACS_EDMG_ENABLED = 16, + QCA_WLAN_VENDOR_ATTR_ACS_EDMG_CHANNEL = 17, + QCA_WLAN_VENDOR_ATTR_ACS_PUNCTURE_BITMAP = 18, + QCA_WLAN_VENDOR_ATTR_ACS_EHT_ENABLED = 19, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ACS_MAX = + QCA_WLAN_VENDOR_ATTR_ACS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_acs_hw_mode - Defines HW mode to be used with the + * vendor command/event QCA_NL80211_VENDOR_SUBCMD_DO_ACS. + * + * @QCA_ACS_MODE_IEEE80211B: 802.11b mode + * @QCA_ACS_MODE_IEEE80211G: 802.11g mode + * @QCA_ACS_MODE_IEEE80211A: 802.11a mode + * @QCA_ACS_MODE_IEEE80211AD: 802.11ad mode + * @QCA_ACS_MODE_IEEE80211ANY: all modes + * @QCA_ACS_MODE_IEEE80211AX: 802.11ax mode + */ +enum qca_wlan_vendor_acs_hw_mode { + QCA_ACS_MODE_IEEE80211B, + QCA_ACS_MODE_IEEE80211G, + QCA_ACS_MODE_IEEE80211A, + QCA_ACS_MODE_IEEE80211AD, + QCA_ACS_MODE_IEEE80211ANY, + QCA_ACS_MODE_IEEE80211AX, +}; + +/** + * enum qca_wlan_vendor_features - Vendor device/driver feature flags + * + * @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key + * management offload, a mechanism where the station's firmware + * does the exchange with the AP to establish the temporal keys + * after roaming, rather than having the user space wpa_supplicant do it. + * @QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY: Device supports automatic + * band selection based on channel selection results. + * @QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS: Device supports + * simultaneous off-channel operations. + * @QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD: Device supports P2P + * Listen offload; a mechanism where the station's firmware takes care of + * responding to incoming Probe Request frames received from other P2P + * Devices whilst in Listen state, rather than having the user space + * wpa_supplicant do it. Information from received P2P requests are + * forwarded from firmware to host whenever the host processor wakes up. + * @QCA_WLAN_VENDOR_FEATURE_OCE_STA: Device supports all OCE non-AP STA + * specific features. + * @QCA_WLAN_VENDOR_FEATURE_OCE_AP: Device supports all OCE AP specific + * features. + * @QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON: Device supports OCE STA-CFON + * specific features only. If a Device sets this bit but not the + * %QCA_WLAN_VENDOR_FEATURE_OCE_AP, the userspace shall assume that + * this Device may not support all OCE AP functionalities but can support + * only OCE STA-CFON functionalities. + * @QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY: Device supports self + * managed regulatory. + * @QCA_WLAN_VENDOR_FEATURE_TWT: Device supports TWT (Target Wake Time). + * @QCA_WLAN_VENDOR_FEATURE_11AX: Device supports 802.11ax (HE) + * @QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT: Device supports 6 GHz band operation + * @QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG: Device is capable of receiving + * and applying thermal configuration through + * %QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL and + * %QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW attributes from + * userspace. + * @QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R: Device supports Adaptive 11r. + * With Adaptive 11r feature, access points advertise the vendor + * specific IEs and MDE but do not include FT AKM in the RSNE. + * The Adaptive 11r supported stations are expected to identify + * such vendor specific IEs and connect to the AP in FT mode though + * the profile is configured in non-FT mode. + * The driver-based SME cases also need to have this support for + * Adaptive 11r to handle the connection and roaming scenarios. + * This flag indicates the support for the same to the user space. + * @QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS: Device supports + * concurrent network sessions on different Wi-Fi bands. This feature + * capability is attributed to the hardware's capability to support + * the same (e.g., DBS). + * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT: Flag indicating whether the + * responses for the respective TWT operations are asynchronous (separate + * event message) from the driver. If not specified, the responses are + * synchronous (in vendor command reply) to the request. Each TWT + * operation is specifically mentioned (against its respective + * documentation) to support either of these or both modes. + * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits + */ +enum qca_wlan_vendor_features { + QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD = 0, + QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY = 1, + QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS = 2, + QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD = 3, + QCA_WLAN_VENDOR_FEATURE_OCE_STA = 4, + QCA_WLAN_VENDOR_FEATURE_OCE_AP = 5, + QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON = 6, + QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY = 7, + QCA_WLAN_VENDOR_FEATURE_TWT = 8, + QCA_WLAN_VENDOR_FEATURE_11AX = 9, + QCA_WLAN_VENDOR_FEATURE_6GHZ_SUPPORT = 10, + QCA_WLAN_VENDOR_FEATURE_THERMAL_CONFIG = 11, + QCA_WLAN_VENDOR_FEATURE_ADAPTIVE_11R = 12, + QCA_WLAN_VENDOR_FEATURE_CONCURRENT_BAND_SESSIONS = 13, + QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT = 14, + NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */ +}; + +/** + * enum qca_wlan_vendor_attr_data_offload_ind - Vendor Data Offload Indication + * + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION: Session corresponding to + * the offloaded data. + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL: Protocol of the offloaded + * data. + * @QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT: Event type for the data offload + * indication. + */ +enum qca_wlan_vendor_attr_data_offload_ind { + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_SESSION, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_PROTOCOL, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_EVENT, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_MAX = + QCA_WLAN_VENDOR_ATTR_DATA_OFFLOAD_IND_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_set_config - Vendor subcmd attributes to set + * OCB config + * + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT: Number of channels in the + * configuration + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE: Size of the schedule + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY: Array of channels + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY: Array of channels to be + * scheduled + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY: Array of NDL channel + * information + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY: Array of NDL + * active state configuration + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS: Configuration flags such as + * OCB_CONFIG_FLAG_80211_FRAME_MODE + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM: Default TX parameters to + * use in the case that a packet is sent without a TX control header + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION: Max duration after the + * last TA received that the local time set by TA is synchronous to other + * communicating OCB STAs. + */ +enum qca_wlan_vendor_attr_ocb_set_config { + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_COUNT = 1, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE = 2, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_CHANNEL_ARRAY = 3, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_ARRAY = 4, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY = 5, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY = 6, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_FLAGS = 7, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_DEF_TX_PARAM = 8, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_TA_MAX_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_set_utc_time - Vendor subcmd attributes to set + * UTC time + * + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE: The UTC time as an array of + * 10 bytes + * @QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR: The time error as an array of + * 5 bytes + */ +enum qca_wlan_vendor_attr_ocb_set_utc_time { + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_VALUE = 1, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_ERROR = 2, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_SET_UTC_TIME_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_start_timing_advert - Vendor subcmd attributes + * to start sending timing advert frames + * + * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ: Cannel frequency + * on which to send the frames + * @QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE: Number of times + * the frame is sent in 5 seconds + */ +enum qca_wlan_vendor_attr_ocb_start_timing_advert { + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_CHANNEL_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_REPEAT_RATE = 2, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_START_TIMING_ADVERT_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_stop_timing_advert - Vendor subcmd attributes + * to stop timing advert + * + * @QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ: The channel + * frequency on which to stop the timing advert + */ +enum qca_wlan_vendor_attr_ocb_stop_timing_advert { + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_CHANNEL_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_STOP_TIMING_ADVERT_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_ocb_get_tsf_response - Vendor subcmd attributes to + * get TSF timer value + * + * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH: Higher 32 bits of the + * timer + * @QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW: Lower 32 bits of the timer + */ +enum qca_wlan_vendor_attr_ocb_get_tsf_resp { + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_HIGH = 1, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_TIMER_LOW = 2, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_MAX = + QCA_WLAN_VENDOR_ATTR_OCB_GET_TSF_RESP_AFTER_LAST - 1 +}; + +enum qca_vendor_attr_get_preferred_freq_list { + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_INVALID, + /* A 32-unsigned value; the interface type/mode for which the preferred + * frequency list is requested (see enum qca_iface_type for possible + * values); used in GET_PREFERRED_FREQ_LIST command from user-space to + * kernel and in the kernel response back to user-space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE, + /* An array of 32-unsigned values; values are frequency (MHz); sent + * from kernel space to user space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST, + /* An array of nested values as per enum qca_wlan_vendor_attr_pcl + * attribute. Each element contains frequency (MHz), weight, and flag + * bit mask indicating how the frequency should be used in P2P + * negotiation; sent from kernel space to user space. + */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_WEIGHED_PCL, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX = + QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_AFTER_LAST - 1 +}; + +enum qca_vendor_attr_probable_oper_channel { + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_INVALID, + /* 32-bit unsigned value; indicates the connection/iface type likely to + * come on this channel (see enum qca_iface_type). + */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE, + /* 32-bit unsigned value; the frequency (MHz) of the probable channel */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX = + QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_AFTER_LAST - 1 +}; + +enum qca_iface_type { + QCA_IFACE_TYPE_STA, + QCA_IFACE_TYPE_AP, + QCA_IFACE_TYPE_P2P_CLIENT, + QCA_IFACE_TYPE_P2P_GO, + QCA_IFACE_TYPE_IBSS, + QCA_IFACE_TYPE_TDLS, +}; + +enum qca_set_band { + QCA_SETBAND_AUTO = 0, + QCA_SETBAND_5G = BIT(0), + QCA_SETBAND_2G = BIT(1), + QCA_SETBAND_6G = BIT(2), +}; + +/** + * enum qca_access_policy - Access control policy + * + * Access control policy is applied on the configured IE + * (QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE). + * To be set with QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY. + * + * @QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED: Deny Wi-Fi connections which match + * the specific configuration (IE) set, i.e., allow all the + * connections which do not match the configuration. + * @QCA_ACCESS_POLICY_DENY_UNLESS_LISTED: Accept Wi-Fi connections which match + * the specific configuration (IE) set, i.e., deny all the + * connections which do not match the configuration. + */ +enum qca_access_policy { + QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED, + QCA_ACCESS_POLICY_DENY_UNLESS_LISTED, +}; + +/** + * enum qca_vendor_attr_tsf_cmd: Vendor attributes for TSF capture + * @QCA_WLAN_VENDOR_ATTR_TSF_CMD: Required (u32) + * Specify the TSF command. Possible values are defined in + * &enum qca_tsf_cmd. + * @QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE: Optional (u64) + * This attribute contains TSF timer value. This attribute is only available + * in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response. + * @QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE: Optional (u64) + * This attribute contains SOC timer value at TSF capture. This attribute is + * only available in %QCA_TSF_GET or %QCA_TSF_SYNC_GET response. + * @QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL: Optional (u32) + * This attribute is used to provide TSF sync interval and only applicable when + * TSF command is %QCA_TSF_SYNC_START. If this attribute is not provided, the + * driver will use the default value. Time unit is in milliseconds. + */ +enum qca_vendor_attr_tsf_cmd { + QCA_WLAN_VENDOR_ATTR_TSF_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TSF_CMD, + QCA_WLAN_VENDOR_ATTR_TSF_TIMER_VALUE, + QCA_WLAN_VENDOR_ATTR_TSF_SOC_TIMER_VALUE, + QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL, + QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TSF_MAX = + QCA_WLAN_VENDOR_ATTR_TSF_AFTER_LAST - 1 +}; + +/** + * enum qca_tsf_cmd: TSF driver commands + * @QCA_TSF_CAPTURE: Initiate TSF Capture + * @QCA_TSF_GET: Get TSF capture value + * @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value + * @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target + * will automatically send TSF report to the host. To query + * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be + * initiated first. + * @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target + * will not automatically send TSF report to the host. If + * %QCA_TSF_AUTO_REPORT_ENABLE is initiated and + * %QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this + * operation needs to be initiated. + * @QCA_TSF_SYNC_START: Start periodic TSF sync feature. The driver periodically + * fetches TSF and host time mapping from the firmware with interval configured + * through the %QCA_WLAN_VENDOR_ATTR_TSF_SYNC_INTERVAL attribute. If the + * interval value is not provided the driver will use the default value. The + * userspace can query the TSF and host time mapping via the %QCA_TSF_GET + * command. + * @QCA_TSF_SYNC_STOP: Stop periodic TSF sync feature. + */ +enum qca_tsf_cmd { + QCA_TSF_CAPTURE, + QCA_TSF_GET, + QCA_TSF_SYNC_GET, + QCA_TSF_AUTO_REPORT_ENABLE, + QCA_TSF_AUTO_REPORT_DISABLE, + QCA_TSF_SYNC_START, + QCA_TSF_SYNC_STOP, +}; + +/** + * enum qca_vendor_attr_wisa_cmd + * @QCA_WLAN_VENDOR_ATTR_WISA_MODE: WISA mode value (u32) + * WISA setup vendor commands + */ +enum qca_vendor_attr_wisa_cmd { + QCA_WLAN_VENDOR_ATTR_WISA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WISA_MODE, + QCA_WLAN_VENDOR_ATTR_WISA_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WISA_MAX = + QCA_WLAN_VENDOR_ATTR_WISA_AFTER_LAST - 1 +}; + +/* IEEE 802.11 Vendor Specific elements */ + +/** + * enum qca_vendor_element_id - QCA Vendor Specific element types + * + * These values are used to identify QCA Vendor Specific elements. The + * payload of the element starts with the three octet OUI (OUI_QCA) and + * is followed by a single octet type which is defined by this enum. + * + * @QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST: P2P preferred channel list. + * This element can be used to specify preference order for supported + * channels. The channels in this list are in preference order (the first + * one has the highest preference) and are described as a pair of + * (global) Operating Class and Channel Number (each one octet) fields. + * + * This extends the standard P2P functionality by providing option to have + * more than one preferred operating channel. When this element is present, + * it replaces the preference indicated in the Operating Channel attribute. + * For supporting other implementations, the Operating Channel attribute is + * expected to be used with the highest preference channel. Similarly, all + * the channels included in this Preferred channel list element are + * expected to be included in the Channel List attribute. + * + * This vendor element may be included in GO Negotiation Request, P2P + * Invitation Request, and Provision Discovery Request frames. + * + * @QCA_VENDOR_ELEM_HE_CAPAB: HE Capabilities element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID. The payload of this + * vendor specific element is defined by the latest P802.11ax draft. + * Please note that the draft is still work in progress and this element + * payload is subject to change. + * + * @QCA_VENDOR_ELEM_HE_OPER: HE Operation element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID. The payload of this + * vendor specific element is defined by the latest P802.11ax draft. + * Please note that the draft is still work in progress and this element + * payload is subject to change. + * + * @QCA_VENDOR_ELEM_RAPS: RAPS element (OFDMA-based Random Access Parameter Set + * element). + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_MU_EDCA_PARAMS: MU EDCA Parameter Set element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_BSS_COLOR_CHANGE: BSS Color Change Announcement element. + * This element can be used for pre-standard publication testing of HE + * before P802.11ax draft assigns the element ID extension. The payload of + * this vendor specific element is defined by the latest P802.11ax draft + * (not including the Element ID Extension field). Please note that the + * draft is still work in progress and this element payload is subject to + * change. + * + * @QCA_VENDOR_ELEM_ALLPLAY: Allplay element + */ +enum qca_vendor_element_id { + QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST = 0, + QCA_VENDOR_ELEM_HE_CAPAB = 1, + QCA_VENDOR_ELEM_HE_OPER = 2, + QCA_VENDOR_ELEM_RAPS = 3, + QCA_VENDOR_ELEM_MU_EDCA_PARAMS = 4, + QCA_VENDOR_ELEM_BSS_COLOR_CHANGE = 5, + QCA_VENDOR_ELEM_ALLPLAY = 6, +}; + +/** + * enum qca_wlan_vendor_scan_priority - Specifies the valid values that the + * vendor scan attribute QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY can take. + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW: Very low priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW: Low priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM: Medium priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH: High priority + * @QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH: Very high priority + */ +enum qca_wlan_vendor_scan_priority { + QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_LOW = 0, + QCA_WLAN_VENDOR_SCAN_PRIORITY_LOW = 1, + QCA_WLAN_VENDOR_SCAN_PRIORITY_MEDIUM = 2, + QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH = 3, + QCA_WLAN_VENDOR_SCAN_PRIORITY_VERY_HIGH = 4, +}; + +/** + * enum qca_wlan_vendor_attr_scan - Specifies vendor scan attributes + * + * @QCA_WLAN_VENDOR_ATTR_SCAN_IE: IEs that should be included as part of scan + * @QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES: Nested unsigned 32-bit attributes + * with frequencies to be scanned (in MHz) + * @QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS: Nested attribute with SSIDs to be scanned + * @QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES: Nested array attribute of supported + * rates to be included + * @QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE: flag used to send probe requests + * at non CCK rate in 2GHz band + * @QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS: Unsigned 32-bit scan flags + * @QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE: Unsigned 64-bit cookie provided by the + * driver for the specific scan request + * @QCA_WLAN_VENDOR_ATTR_SCAN_STATUS: Unsigned 8-bit status of the scan + * request decoded as in enum scan_status + * @QCA_WLAN_VENDOR_ATTR_SCAN_MAC: 6-byte MAC address to use when randomisation + * scan flag is set + * @QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK: 6-byte MAC address mask to be used with + * randomisation + * @QCA_WLAN_VENDOR_ATTR_SCAN_BSSID: 6-byte MAC address representing the + * specific BSSID to scan for. + * @QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME: Unsigned 64-bit dwell time in + * microseconds. This is a common value which applies across all + * frequencies specified by QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES. + * @QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY: Priority of vendor scan relative to + * other scan requests. It is a u32 attribute and takes values from enum + * qca_wlan_vendor_scan_priority. This is an optional attribute. + * If this attribute is not configured, the driver shall use + * QCA_WLAN_VENDOR_SCAN_PRIORITY_HIGH as the priority of vendor scan. + */ +enum qca_wlan_vendor_attr_scan { + QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0, + QCA_WLAN_VENDOR_ATTR_SCAN_IE = 1, + QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES = 2, + QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS = 3, + QCA_WLAN_VENDOR_ATTR_SCAN_SUPP_RATES = 4, + QCA_WLAN_VENDOR_ATTR_SCAN_TX_NO_CCK_RATE = 5, + QCA_WLAN_VENDOR_ATTR_SCAN_FLAGS = 6, + QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE = 7, + QCA_WLAN_VENDOR_ATTR_SCAN_STATUS = 8, + QCA_WLAN_VENDOR_ATTR_SCAN_MAC = 9, + QCA_WLAN_VENDOR_ATTR_SCAN_MAC_MASK = 10, + QCA_WLAN_VENDOR_ATTR_SCAN_BSSID = 11, + QCA_WLAN_VENDOR_ATTR_SCAN_DWELL_TIME = 12, + QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13, + QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SCAN_MAX = + QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1 +}; + +/** + * enum scan_status - Specifies the valid values the vendor scan attribute + * QCA_WLAN_VENDOR_ATTR_SCAN_STATUS can take + * + * @VENDOR_SCAN_STATUS_NEW_RESULTS: implies the vendor scan is successful with + * new scan results + * @VENDOR_SCAN_STATUS_ABORTED: implies the vendor scan was aborted in-between + */ +enum scan_status { + VENDOR_SCAN_STATUS_NEW_RESULTS, + VENDOR_SCAN_STATUS_ABORTED, + VENDOR_SCAN_STATUS_MAX, +}; + +/** + * enum qca_vendor_attr_ota_test - Specifies the values for vendor + * command QCA_NL80211_VENDOR_SUBCMD_OTA_TEST + * @QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE: enable ota test + */ +enum qca_vendor_attr_ota_test { + QCA_WLAN_VENDOR_ATTR_OTA_TEST_INVALID, + /* 8-bit unsigned value to indicate if OTA test is enabled */ + QCA_WLAN_VENDOR_ATTR_OTA_TEST_ENABLE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OTA_TEST_MAX = + QCA_WLAN_VENDOR_ATTR_OTA_TEST_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_attr_txpower_scale - vendor sub commands index + * + * @QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE: scaling value + */ +enum qca_vendor_attr_txpower_scale { + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_INVALID, + /* 8-bit unsigned value to indicate the scaling of tx power */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_MAX = + QCA_WLAN_VENDOR_ATTR_TXPOWER_SCALE_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_attr_txpower_decr_db - Attributes for TX power decrease + * + * These attributes are used with QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_DECR_DB. + */ +enum qca_vendor_attr_txpower_decr_db { + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_INVALID, + /* 8-bit unsigned value to indicate the reduction of TX power in dB for + * a virtual interface. + */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_MAX = + QCA_WLAN_VENDOR_ATTR_TXPOWER_DECR_DB_AFTER_LAST - 1 +}; + +/* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and + * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION subcommands. + */ +enum qca_wlan_vendor_attr_config { + QCA_WLAN_VENDOR_ATTR_CONFIG_INVALID = 0, + /* Unsigned 32-bit value to set the DTIM period. + * Whether the wifi chipset wakes at every dtim beacon or a multiple of + * the DTIM period. If DTIM is set to 3, the STA shall wake up every 3 + * DTIM beacons. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_DTIM = 1, + /* Unsigned 32-bit value to set the wifi_iface stats averaging factor + * used to calculate statistics like average the TSF offset or average + * number of frame leaked. + * For instance, upon Beacon frame reception: + * current_avg = ((beacon_TSF - TBTT) * factor + previous_avg * (0x10000 - factor) ) / 0x10000 + * For instance, when evaluating leaky APs: + * current_avg = ((num frame received within guard time) * factor + previous_avg * (0x10000 - factor)) / 0x10000 + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR = 2, + /* Unsigned 32-bit value to configure guard time, i.e., when + * implementing IEEE power management based on frame control PM bit, how + * long the driver waits before shutting down the radio and after + * receiving an ACK frame for a Data frame with PM bit set. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME = 3, + /* Unsigned 32-bit value to change the FTM capability dynamically */ + QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT = 4, + /* Unsigned 16-bit value to configure maximum TX rate dynamically */ + QCA_WLAN_VENDOR_ATTR_CONF_TX_RATE = 5, + /* Unsigned 32-bit value to configure the number of continuous + * Beacon Miss which shall be used by the firmware to penalize + * the RSSI. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS = 6, + /* Unsigned 8-bit value to configure the channel avoidance indication + * behavior. Firmware to send only one indication and ignore duplicate + * indications when set to avoid multiple Apps wakeups. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND = 7, + /* 8-bit unsigned value to configure the maximum TX MPDU for + * aggregation. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION = 8, + /* 8-bit unsigned value to configure the maximum RX MPDU for + * aggregation. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION = 9, + /* 8-bit unsigned value to configure the Non aggregrate/11g sw + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY = 10, + /* 8-bit unsigned value to configure the aggregrate sw + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY = 11, + /* 8-bit unsigned value to configure the MGMT frame + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY = 12, + /* 8-bit unsigned value to configure the CTRL frame + * retry threshold (0 disable, 31 max). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY = 13, + /* 8-bit unsigned value to configure the propagation delay for + * 2G/5G band (0~63, units in us) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY = 14, + /* Unsigned 32-bit value to configure the number of unicast TX fail + * packet count. The peer is disconnected once this threshold is + * reached. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT = 15, + /* Attribute used to set scan default IEs to the driver. + * + * These IEs can be used by scan operations that will be initiated by + * the driver/firmware. + * + * For further scan requests coming to the driver, these IEs should be + * merged with the IEs received along with scan request coming to the + * driver. If a particular IE is present in the scan default IEs but not + * present in the scan request, then that IE should be added to the IEs + * sent in the Probe Request frames for that scan request. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES = 16, + /* Unsigned 32-bit attribute for generic commands */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_COMMAND = 17, + /* Unsigned 32-bit value attribute for generic commands */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_VALUE = 18, + /* Unsigned 32-bit data attribute for generic command response */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA = 19, + /* Unsigned 32-bit length attribute for + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_LENGTH = 20, + /* Unsigned 32-bit flags attribute for + * QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_FLAGS = 21, + /* Unsigned 32-bit, defining the access policy. + * See enum qca_access_policy. Used with + * QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY = 22, + /* Sets the list of full set of IEs for which a specific access policy + * has to be applied. Used along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY to control the access. + * Zero length payload can be used to clear this access constraint. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST = 23, + /* Unsigned 32-bit, specifies the interface index (netdev) for which the + * corresponding configurations are applied. If the interface index is + * not specified, the configurations are attributed to the respective + * wiphy. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_IFINDEX = 24, + /* 8-bit unsigned value to trigger QPower: 1-Enable, 0-Disable */ + QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER = 25, + /* 8-bit unsigned value to configure the driver and below layers to + * ignore the assoc disallowed set by APs while connecting + * 1-Ignore, 0-Don't ignore + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED = 26, + /* 32-bit unsigned value to trigger antenna diversity features: + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA = 27, + /* 32-bit unsigned value to configure specific chain antenna */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN = 28, + /* 32-bit unsigned value to trigger cycle selftest + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST = 29, + /* 32-bit unsigned to configure the cycle time of selftest + * the unit is micro-second + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL = 30, + /* 32-bit unsigned value to set reorder timeout for AC_VO */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE = 31, + /* 32-bit unsigned value to set reorder timeout for AC_VI */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO = 32, + /* 32-bit unsigned value to set reorder timeout for AC_BE */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT = 33, + /* 32-bit unsigned value to set reorder timeout for AC_BK */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND = 34, + /* 6-byte MAC address to point out the specific peer */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC = 35, + /* 32-bit unsigned value to set window size for specific peer */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT = 36, + /* 8-bit unsigned value to set the beacon miss threshold in 2.4 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24 = 37, + /* 8-bit unsigned value to set the beacon miss threshold in 5 GHz */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5 = 38, + /* 32-bit unsigned value to configure 5 or 10 MHz channel width for + * station device while in disconnect state. The attribute use the + * value of enum nl80211_chan_width: NL80211_CHAN_WIDTH_5 means 5 MHz, + * NL80211_CHAN_WIDTH_10 means 10 MHz. If set, the device work in 5 or + * 10 MHz channel width, the station will not connect to a BSS using 20 + * MHz or higher bandwidth. Set to NL80211_CHAN_WIDTH_20_NOHT to + * clear this constraint. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SUB20_CHAN_WIDTH = 39, + /* 32-bit unsigned value to configure the propagation absolute delay + * for 2G/5G band (units in us) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY = 40, + /* 32-bit unsigned value to set probe period */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD = 41, + /* 32-bit unsigned value to set stay period */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD = 42, + /* 32-bit unsigned value to set snr diff */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF = 43, + /* 32-bit unsigned value to set probe dwell time */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME = 44, + /* 32-bit unsigned value to set mgmt snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT = 45, + /* 32-bit unsigned value to set data snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT = 46, + /* 32-bit unsigned value to set ack snr weight */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT = 47, + /* 32-bit unsigned value to configure the listen interval. + * This is in units of beacon intervals. This configuration alters + * the negotiated listen interval with the AP during the connection. + * It is highly recommended to configure a value less than or equal to + * the one negotiated during the association. Configuring any greater + * value can have adverse effects (frame loss, AP disassociating STA, + * etc.). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL = 48, + /* + * 8 bit unsigned value that is set on an AP/GO virtual interface to + * disable operations that would cause the AP/GO to leave its operating + * channel. + * + * This will restrict the scans to the AP/GO operating channel and the + * channels of the other band, if DBS is supported.A STA/CLI interface + * brought up after this setting is enabled, will be restricted to + * connecting to devices only on the AP/GO interface's operating channel + * or on the other band in DBS case. P2P supported channel list is + * modified, to only include AP interface's operating-channel and the + * channels of the other band if DBS is supported. + * + * These restrictions are only applicable as long as the AP/GO interface + * is alive. If the AP/GO interface is brought down then this + * setting/restriction is forgotten. + * + * If this variable is set on an AP/GO interface while a multi-channel + * concurrent session is active, it has no effect on the operation of + * the current interfaces, other than restricting the scan to the AP/GO + * operating channel and the other band channels if DBS is supported. + * However, if the STA is brought down and restarted then the new STA + * connection will either be formed on the AP/GO channel or on the + * other band in a DBS case. This is because of the scan being + * restricted on these channels as mentioned above. + * + * 1-Restrict / 0-Don't restrict offchannel operations. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL = 49, + /* + * 8 bit unsigned value to enable/disable LRO (Large Receive Offload) + * on an interface. + * 1 - Enable, 0 - Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LRO = 50, + + /* + * 8 bit unsigned value to globally enable/disable scan + * 1 - Enable, 0 - Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE = 51, + + /* 8-bit unsigned value to set the total beacon miss count + * This parameter will set the total beacon miss count. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT = 52, + + /* Unsigned 32-bit value to configure the number of continuous + * Beacon Miss which shall be used by the firmware to penalize + * the RSSI for BTC. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS_BTC = 53, + + /* 8-bit unsigned value to configure the driver and below layers to + * enable/disable all FILS features. + * 0-enable, 1-disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS = 54, + + /* 16-bit unsigned value to configure the level of WLAN latency + * module. See enum qca_wlan_vendor_attr_config_latency_level. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL = 55, + + /* 8-bit unsigned value indicating the driver to use the RSNE as-is from + * the connect interface. Exclusively used for the scenarios where the + * device is used as a test bed device with special functionality and + * not recommended for production. This helps driver to not validate the + * RSNE passed from user space and thus allow arbitrary IE data to be + * used for testing purposes. + * 1-enable, 0-disable. + * Applications set/reset this configuration. If not reset, this + * parameter remains in use until the driver is unloaded. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE = 56, + + /* 8-bit unsigned value to trigger green Tx power saving. + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_GTX = 57, + + /* Attribute to configure disconnect IEs to the driver. + * This carries an array of unsigned 8-bit characters. + * + * If this is configured, driver shall fill the IEs in disassoc/deauth + * frame. + * These IEs are expected to be considered only for the next + * immediate disconnection (disassoc/deauth frame) originated by + * the DUT, irrespective of the entity (user space/driver/firmware) + * triggering the disconnection. + * The host drivers are not expected to use the IEs set through + * this interface for further disconnections after the first immediate + * disconnection initiated post the configuration. + * If the IEs are also updated through cfg80211 interface (after the + * enhancement to cfg80211_disconnect), host driver is expected to + * take the union of IEs from both of these interfaces and send in + * further disassoc/deauth frames. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES = 58, + + /* 8-bit unsigned value for ELNA bypass. + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ELNA_BYPASS = 59, + + /* 8-bit unsigned value. This attribute enables/disables the host driver + * to send the Beacon Report Response with failure reason for the + * scenarios where STA cannot honor the Beacon Report Request from AP. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL = 60, + + /* 8-bit unsigned value. This attribute enables/disables the host driver + * to send roam reason information in the Reassociation Request frame to + * the target AP when roaming within the same ESS. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ROAM_REASON = 61, + + /* 32-bit unsigned value to configure different PHY modes to the + * driver/firmware. The possible values are defined in + * enum qca_wlan_vendor_phy_mode. The configuration will be reset to + * default value, i.e., QCA_WLAN_VENDOR_PHY_MODE_AUTO upon restarting + * the driver. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE = 62, + + /* 8-bit unsigned value to configure the maximum supported channel width + * for STA mode. If this value is configured when STA is in connected + * state, it should not exceed the negotiated channel width. If it is + * configured when STA is in disconnected state, the configured value + * will take effect for the next immediate connection. + * Possible values are: + * NL80211_CHAN_WIDTH_20 + * NL80211_CHAN_WIDTH_40 + * NL80211_CHAN_WIDTH_80 + * NL80211_CHAN_WIDTH_80P80 + * NL80211_CHAN_WIDTH_160 + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH = 63, + + /* 8-bit unsigned value to enable/disable dynamic bandwidth adjustment. + * This attribute is only applicable for STA mode. When dynamic + * bandwidth adjustment is disabled, STA will use static channel width + * the value of which is negotiated during connection. + * 1-enable (default), 0-disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_DYNAMIC_BW = 64, + + /* 8-bit unsigned value to configure the maximum number of subframes of + * TX MSDU for aggregation. Possible values are 0-31. When set to 0, + * it is decided by the hardware. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION = 65, + + /* 8-bit unsigned value to configure the maximum number of subframes of + * RX MSDU for aggregation. Possible values are 0-31. When set to 0, + * it is decided by the hardware. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION = 66, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the LDPC capability of the device. When configured in + * the disconnected state, the updated configuration will be considered + * for the immediately following connection attempt. If this + * configuration is modified while the device is in the connected state, + * the LDPC TX will be updated with this configuration immediately, + * while the LDPC RX configuration update will take place starting from + * the subsequent association attempt. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC = 67, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the TX STBC capability of the device. When configured + * in the disconnected state, the updated configuration will be + * considered for the immediately following connection attempt. If the + * connection is formed with TX STBC enabled and if this configuration + * is disabled during that association, the TX will be impacted + * immediately. Further connection attempts will disable TX STBC. + * However, enabling the TX STBC for a connected session with disabled + * capability is not allowed and will fail. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC = 68, + + /* 8-bit unsigned value. This attribute is used to dynamically + * enable/disable the RX STBC capability of the device. When configured + * in the disconnected state, the updated configuration will be + * considered for the immediately following connection attempt. If the + * configuration is modified in the connected state, there will be no + * impact for the current association, but further connection attempts + * will use the updated configuration. + * 1-Enable, 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC = 69, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams. When configured in the disconnected + * state, the updated configuration will be considered for the + * immediately following connection attempt. If the NSS is updated after + * the connection, the updated NSS value is notified to the peer using + * the Operating Mode Notification/Spatial Multiplexing Power Save + * frame. The updated NSS value after the connection shall not be + * greater than the one negotiated during the connection. Any such + * higher value configuration shall be returned with a failure. + * Only symmetric NSS configuration (such as 2X2 or 1X1) can be done + * using this attribute. QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS and + * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attributes shall be used to + * configure the asymmetric NSS configuration (such as 1X2). + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NSS = 70, + /* 8-bit unsigned value to trigger Optimized Power Management: + * 1-Enable, 0-Disable + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_OPTIMIZED_POWER_MANAGEMENT = 71, + + /* 8-bit unsigned value. This attribute takes the QoS/access category + * value represented by the enum qca_wlan_ac_type and expects the driver + * to upgrade the UDP frames to this access category. The value of + * QCA_WLAN_AC_ALL is invalid for this attribute. This will override the + * DSCP value configured in the frame with the intention to only upgrade + * the access category. That said, it is not intended to downgrade the + * access category for the frames. + * Set the value to QCA_WLAN_AC_BK if the QoS upgrade needs to be + * disabled, as BK is of the lowest priority and an upgrade to it does + * not result in any changes for the frames. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_UDP_QOS_UPGRADE = 72, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for transmitting data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_TX_CHAINS = 73, + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of chains to be used for receiving data. This + * configuration is allowed only when in connected state and will be + * effective until disconnected. The driver rejects this configuration + * if the number of spatial streams being used in the current connection + * cannot be supported by this configuration. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_NUM_RX_CHAINS = 74, + + /* 8-bit unsigned value to configure ANI setting type. + * See &enum qca_wlan_ani_setting for possible values. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_SETTING = 75, + /* 32-bit signed value to configure ANI level. This is used when + * ANI settings type is &QCA_WLAN_ANI_SETTING_FIXED. + * The set and get of ANI level with &QCA_WLAN_ANI_SETTING_AUTO + * is invalid, the driver will return a failure. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ANI_LEVEL = 76, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for transmitting the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The TX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute the driver + * will update the TX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS = 77, + + /* 8-bit unsigned value. This attribute is used to dynamically configure + * the number of spatial streams used for receiving the data. When + * configured in the disconnected state, the configured value will + * be considered for the following connection attempt. + * If the NSS is updated after the connection, the updated NSS value + * is notified to the peer using the Operating Mode Notification/Spatial + * Multiplexing Power Save frame. + * The RX NSS value configured after the connection shall not be greater + * than the value negotiated during the connection. Any such higher + * value configuration shall be treated as invalid configuration by + * the driver. This attribute shall be configured along with + * QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS attribute to define the symmetric + * configuration (such as 2X2 or 1X1) or the asymmetric + * configuration (such as 1X2). + * If QCA_WLAN_VENDOR_ATTR_CONFIG_NSS attribute is also provided along + * with this QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS attribute the driver + * will update the RX NSS based on QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS = 78, + + /* + * 8-bit unsigned value. This attribute, when set, indicates whether the + * specified interface is the primary STA interface when there are more + * than one STA interfaces concurrently active. + * + * This configuration helps the firmware/hardware to support certain + * features (e.g., roaming) on this primary interface, if the same + * cannot be supported on the concurrent STA interfaces simultaneously. + * + * This configuration is only applicable for a single STA interface on + * a device and gives the priority for it only over other concurrent STA + * interfaces. + * + * If the device is a multi wiphy/soc, this configuration applies to a + * single STA interface across the wiphys. + * + * 1-Enable (is the primary STA), 0-Disable (is not the primary STA) + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY = 79, + + /* + * 8-bit unsigned value. This attribute can be used to configure the + * driver to enable/disable FT-over-DS feature. Possible values for + * this attribute are 1-Enable and 0-Disable. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS = 80, + + /* + * 8-bit unsigned value. This attribute can be used to configure the + * firmware to enable/disable ARP/NS offload feature. Possible values + * for this attribute are 0-Disable and 1-Enable. + * + * This attribute is only applicable for STA/P2P-Client interface, + * and is optional, default behavior is ARP/NS offload enabled. + * + * This attribute can be set in disconnected and connected state, and + * will restore to the default behavior if the interface is closed. + */ + QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD = 81, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1, +}; + +/* Compatibility defines for previously used incorrect enum + * qca_wlan_vendor_attr_config names. These values should not be used in any + * new implementation. */ +#define QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES \ + QCA_WLAN_VENDOR_ATTR_CONFIG_DISCONNECT_IES +#define QCA_WLAN_VENDOR_ATTR_BEACON_REPORT_FAIL \ + QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_REPORT_FAIL + +/** + * enum qca_wlan_ani_setting - ANI setting type + * @QCA_WLAN_ANI_SETTING_AUTO: Automatically determine ANI level + * @QCA_WLAN_ANI_SETTING_FIXED: Fix ANI level to the dBm parameter + */ +enum qca_wlan_ani_setting { + QCA_WLAN_ANI_SETTING_AUTO = 0, + QCA_WLAN_ANI_SETTING_FIXED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_sap_config - Parameters for AP configuration + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL: Optional (u8) + * Channel number on which Access Point should restart. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY: Optional (u32) + * Channel center frequency (MHz) on which the access point should restart. + */ +enum qca_wlan_vendor_attr_sap_config { + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL = 1, + + /* List of frequencies on which AP is expected to operate. + * This is irrespective of ACS configuration. This list is a priority + * based one and is looked for before the AP is created to ensure the + * best concurrency sessions (avoid MCC and use DBS/SCC) co-exist in + * the system. + */ + QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST = 2, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_FREQUENCY = 3, + + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_sap_conditional_chan_switch - Parameters for AP + * conditional channel switch + */ +enum qca_wlan_vendor_attr_sap_conditional_chan_switch { + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_INVALID = 0, + /* Priority based frequency list (an array of u32 values in host byte + * order) + */ + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_FREQ_LIST = 1, + /* Status of the conditional switch (u32). + * 0: Success, Non-zero: Failure + */ + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS = 2, + + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_MAX = + QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_gpio_attr - Parameters for GPIO configuration + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND: Required (u32) + * value to specify the GPIO command. Please refer to enum qca_gpio_cmd_type + * for the available values. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM: Required (u32) + * value to specify the GPIO number. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG or %QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE: Required (u32) + * value to specify the GPIO output level. Please refer to enum qca_gpio_value + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_OUTPUT. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE: Optional (u32) + * value to specify the GPIO pull type. Please refer to enum qca_gpio_pull_type + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE: Optional (u32) + * value to specify the GPIO interrupt mode. Please refer to enum + * qca_gpio_interrupt_mode for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR: Optional (u32) + * value to specify the GPIO direction. Please refer to enum qca_gpio_direction + * for the available values. + * This is required, when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG and + * %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG attribute is not present. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG + * attribute is present. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG: Optional (u32) + * Value to specify the mux config. Meaning of a given value is dependent + * on the target chipset and GPIO pin. Must be of the range 0-15. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to 0. + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE: Optional (u32) + * Value to specify the drive, refer to enum qca_gpio_drive. + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. Defaults to QCA_WLAN_GPIO_DRIVE_2MA(0). + * + * @QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG: Optional (flag) + * Optional when %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND is + * %QCA_WLAN_VENDOR_GPIO_CONFIG. When present this attribute signals that all + * other parameters for the given GPIO will be obtained from internal + * configuration. Only %QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM must be + * specified to indicate the GPIO pin being configured. + */ +enum qca_wlan_gpio_attr { + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INVALID = 0, + /* Unsigned 32-bit attribute for GPIO command */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_COMMAND = 1, + /* Unsigned 32-bit attribute for GPIO PIN number to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PINNUM = 2, + /* Unsigned 32-bit attribute for GPIO value to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_VALUE = 3, + /* Unsigned 32-bit attribute for GPIO pull type */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_PULL_TYPE = 4, + /* Unsigned 32-bit attribute for GPIO interrupt mode */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTR_MODE = 5, + /* Unsigned 32-bit attribute for GPIO direction to configure */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DIR = 6, + /* Unsigned 32-bit attribute for GPIO mux config */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MUX_CONFIG = 7, + /* Unsigned 32-bit attribute for GPIO drive */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_DRIVE = 8, + /* Flag attribute for using internal GPIO configuration */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_INTERNAL_CONFIG = 9, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST, + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_GPIO_PARAM_LAST - 1 +}; + +/** + * enum gpio_cmd_type - GPIO configuration command type + * @QCA_WLAN_VENDOR_GPIO_CONFIG: Set GPIO configuration info + * @QCA_WLAN_VENDOR_GPIO_OUTPUT: Set GPIO output level + */ +enum qca_gpio_cmd_type { + QCA_WLAN_VENDOR_GPIO_CONFIG = 0, + QCA_WLAN_VENDOR_GPIO_OUTPUT = 1, +}; + +/** + * enum qca_gpio_pull_type - GPIO pull type + * @QCA_WLAN_GPIO_PULL_NONE: Set GPIO pull type to none + * @QCA_WLAN_GPIO_PULL_UP: Set GPIO pull up + * @QCA_WLAN_GPIO_PULL_DOWN: Set GPIO pull down + */ +enum qca_gpio_pull_type { + QCA_WLAN_GPIO_PULL_NONE = 0, + QCA_WLAN_GPIO_PULL_UP = 1, + QCA_WLAN_GPIO_PULL_DOWN = 2, + QCA_WLAN_GPIO_PULL_MAX, +}; + +/** + * enum qca_gpio_direction - GPIO direction + * @QCA_WLAN_GPIO_INPUT: Set GPIO as input mode + * @QCA_WLAN_GPIO_OUTPUT: Set GPIO as output mode + * @QCA_WLAN_GPIO_VALUE_MAX: Invalid value + */ +enum qca_gpio_direction { + QCA_WLAN_GPIO_INPUT = 0, + QCA_WLAN_GPIO_OUTPUT = 1, + QCA_WLAN_GPIO_DIR_MAX, +}; + +/** + * enum qca_gpio_value - GPIO Value + * @QCA_WLAN_GPIO_LEVEL_LOW: set gpio output level to low + * @QCA_WLAN_GPIO_LEVEL_HIGH: set gpio output level to high + * @QCA_WLAN_GPIO_LEVEL_MAX: Invalid value + */ +enum qca_gpio_value { + QCA_WLAN_GPIO_LEVEL_LOW = 0, + QCA_WLAN_GPIO_LEVEL_HIGH = 1, + QCA_WLAN_GPIO_LEVEL_MAX, +}; + +/** + * enum gpio_interrupt_mode - GPIO interrupt mode + * @QCA_WLAN_GPIO_INTMODE_DISABLE: Disable interrupt trigger + * @QCA_WLAN_GPIO_INTMODE_RISING_EDGE: Interrupt with GPIO rising edge trigger + * @QCA_WLAN_GPIO_INTMODE_FALLING_EDGE: Interrupt with GPIO falling edge trigger + * @QCA_WLAN_GPIO_INTMODE_BOTH_EDGE: Interrupt with GPIO both edge trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_LOW: Interrupt with GPIO level low trigger + * @QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH: Interrupt with GPIO level high trigger + * @QCA_WLAN_GPIO_INTMODE_MAX: Invalid value + */ +enum qca_gpio_interrupt_mode { + QCA_WLAN_GPIO_INTMODE_DISABLE = 0, + QCA_WLAN_GPIO_INTMODE_RISING_EDGE = 1, + QCA_WLAN_GPIO_INTMODE_FALLING_EDGE = 2, + QCA_WLAN_GPIO_INTMODE_BOTH_EDGE = 3, + QCA_WLAN_GPIO_INTMODE_LEVEL_LOW = 4, + QCA_WLAN_GPIO_INTMODE_LEVEL_HIGH = 5, + QCA_WLAN_GPIO_INTMODE_MAX, +}; + +/** + * enum qca_gpio_drive - GPIO drive + * @QCA_WLAN_GPIO_DRIVE_2MA: drive 2MA + * @QCA_WLAN_GPIO_DRIVE_4MA: drive 4MA + * @QCA_WLAN_GPIO_DRIVE_6MA: drive 6MA + * @QCA_WLAN_GPIO_DRIVE_8MA: drive 8MA + * @QCA_WLAN_GPIO_DRIVE_10MA: drive 10MA + * @QCA_WLAN_GPIO_DRIVE_12MA: drive 12MA + * @QCA_WLAN_GPIO_DRIVE_14MA: drive 14MA + * @QCA_WLAN_GPIO_DRIVE_16MA: drive 16MA + * @QCA_WLAN_GPIO_DRIVE_MAX: invalid GPIO drive + */ +enum qca_gpio_drive { + QCA_WLAN_GPIO_DRIVE_2MA = 0, + QCA_WLAN_GPIO_DRIVE_4MA = 1, + QCA_WLAN_GPIO_DRIVE_6MA = 2, + QCA_WLAN_GPIO_DRIVE_8MA = 3, + QCA_WLAN_GPIO_DRIVE_10MA = 4, + QCA_WLAN_GPIO_DRIVE_12MA = 5, + QCA_WLAN_GPIO_DRIVE_14MA = 6, + QCA_WLAN_GPIO_DRIVE_16MA = 7, + QCA_WLAN_GPIO_DRIVE_MAX, +}; + +/** + * qca_wlan_set_qdepth_thresh_attr - Parameters for setting + * MSDUQ depth threshold per peer per tid in the target + * + * Associated Vendor Command: + * QCA_NL80211_VENDOR_SUBCMD_SET_QDEPTH_THRESH + */ +enum qca_wlan_set_qdepth_thresh_attr { + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_INVALID = 0, + /* 6-byte MAC address */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_MAC_ADDR, + /* Unsigned 32-bit attribute for holding the TID */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_TID, + /* Unsigned 32-bit attribute for holding the update mask + * bit 0 - Update high priority msdu qdepth threshold + * bit 1 - Update low priority msdu qdepth threshold + * bit 2 - Update UDP msdu qdepth threshold + * bit 3 - Update Non UDP msdu qdepth threshold + * rest of bits are reserved + */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_UPDATE_MASK, + /* Unsigned 32-bit attribute for holding the threshold value */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_VALUE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_LAST, + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_MAX = + QCA_WLAN_VENDOR_ATTR_QDEPTH_THRESH_LAST - 1, +}; + +/** + * enum qca_acs_dfs_mode - Defines different types of DFS channel + * configurations for ACS operation. + * + * @QCA_ACS_DFS_MODE_NONE: Refer to invalid DFS mode + * @QCA_ACS_DFS_MODE_ENABLE: Consider DFS channels in ACS operation + * @QCA_ACS_DFS_MODE_DISABLE: Do not consider DFS channels in ACS operation + * @QCA_ACS_DFS_MODE_DEPRIORITIZE: Deprioritize DFS channels in ACS operation + */ +enum qca_acs_dfs_mode { + QCA_ACS_DFS_MODE_NONE = 0, + QCA_ACS_DFS_MODE_ENABLE = 1, + QCA_ACS_DFS_MODE_DISABLE = 2, + QCA_ACS_DFS_MODE_DEPRIORITIZE = 3, +}; + +/** + * enum qca_wlan_vendor_attr_acs_config - Defines Configuration attributes + * used by the vendor command QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE: Required (u8) + * DFS mode for ACS operation from enum qca_acs_dfs_mode. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT: Required (u8) + * channel number hint for ACS operation, if valid channel is specified then + * ACS operation gives priority to this channel. + * Note: If both the driver and user space application supports the 6 GHz band, + * this attribute is deprecated and QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT + * should be used. + * To maintain backward compatibility, QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT: Required (u32). + * Channel center frequency (MHz) hint for ACS operation, if a valid center + * frequency is specified, ACS operation gives priority to this channel. + */ +enum qca_wlan_vendor_attr_acs_config { + QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE = 1, + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT = 2, + QCA_WLAN_VENDOR_ATTR_ACS_FREQUENCY_HINT = 3, + + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX = + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_hw_capability - Wi-Fi hardware capability + */ +enum qca_wlan_vendor_attr_get_hw_capability { + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_INVALID, + /* Antenna isolation + * An attribute used in the response. + * The content of this attribute is encoded in a byte array. Each byte + * value is an antenna isolation value. The array length is the number + * of antennas. + */ + QCA_WLAN_VENDOR_ATTR_ANTENNA_ISOLATION, + /* Request HW capability + * An attribute used in the request. + * The content of this attribute is a u32 array for one or more of + * hardware capabilities (attribute IDs) that are being requested. Each + * u32 value has a value from this + * enum qca_wlan_vendor_attr_get_hw_capability + * identifying which capabilities are requested. + */ + QCA_WLAN_VENDOR_ATTR_GET_HW_CAPABILITY, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_MAX = + QCA_WLAN_VENDOR_ATTR_HW_CAPABILITY_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ll_stats_ext - Attributes for MAC layer monitoring + * offload which is an extension for LL_STATS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD: Monitoring period. Unit in ms. + * If MAC counters do not exceed the threshold, FW will report monitored + * link layer counters periodically as this setting. The first report is + * always triggered by this timer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD: It is a percentage (1-99). + * For each MAC layer counter, FW holds two copies. One is the current value. + * The other is the last report. Once a current counter's increment is larger + * than the threshold, FW will indicate that counter to host even if the + * monitoring timer does not expire. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG: Peer STA power state change + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID: TID of MSDU + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU: Count of MSDU with the same + * failure code. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS: TX failure code + * 1: TX packet discarded + * 2: No ACK + * 3: Postpone + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS: peer MAC address + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE: Peer STA current state + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL: Global threshold. + * Threshold for all monitored parameters. If per counter dedicated threshold + * is not enabled, this threshold will take effect. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE: Indicate what triggers this + * event, PERORID_TIMEOUT == 1, THRESH_EXCEED == 0. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID: interface ID + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID: peer ID + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP: bitmap for TX counters + * Bit0: TX counter unit in MSDU + * Bit1: TX counter unit in MPDU + * Bit2: TX counter unit in PPDU + * Bit3: TX counter unit in byte + * Bit4: Dropped MSDUs + * Bit5: Dropped Bytes + * Bit6: MPDU retry counter + * Bit7: MPDU failure counter + * Bit8: PPDU failure counter + * Bit9: MPDU aggregation counter + * Bit10: MCS counter for ACKed MPDUs + * Bit11: MCS counter for Failed MPDUs + * Bit12: TX Delay counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP: bitmap for RX counters + * Bit0: MAC RX counter unit in MPDU + * Bit1: MAC RX counter unit in byte + * Bit2: PHY RX counter unit in PPDU + * Bit3: PHY RX counter unit in byte + * Bit4: Disorder counter + * Bit5: Retry counter + * Bit6: Duplication counter + * Bit7: Discard counter + * Bit8: MPDU aggregation size counter + * Bit9: MCS counter + * Bit10: Peer STA power state change (wake to sleep) counter + * Bit11: Peer STA power save counter, total time in PS mode + * Bit12: Probe request counter + * Bit13: Other management frames counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP: bitmap for CCA + * Bit0: Idle time + * Bit1: TX time + * Bit2: time RX in current bss + * Bit3: Out of current bss time + * Bit4: Wireless medium busy time + * Bit5: RX in bad condition time + * Bit6: TX in bad condition time + * Bit7: time wlan card not available + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP: bitmap for signal + * Bit0: Per channel SNR counter + * Bit1: Per channel noise floor counter + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM: number of peers + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM: number of channels + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_AC_RX_NUM: number of RX stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS: per channel BSS CCA stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER: container for per PEER stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU: Number of total TX MSDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU: Number of total TX MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU: Number of total TX PPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES: bytes of TX data + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP: Number of dropped TX packets + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES: Bytes dropped + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY: waiting time without an ACK + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK: number of MPDU not-ACKed + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK: number of PPDU not-ACKed + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM: + * aggregation stats buffer length + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM: length of mcs stats + * buffer for ACKed MPDUs. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM: length of mcs stats + * buffer for failed MPDUs. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE: + * length of delay stats array. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR: TX aggregation stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS: MCS stats for ACKed MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS: MCS stats for failed MPDUs + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY: tx delay stats + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU: MPDUs received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES: bytes received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU: PPDU received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES: PPDU bytes received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST: packets lost + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY: number of RX packets + * flagged as retransmissions + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP: number of RX packets + * flagged as duplicated + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD: number of RX + * packets discarded + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM: length of RX aggregation + * stats buffer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM: length of RX mcs + * stats buffer. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS: RX mcs stats buffer + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR: aggregation stats buffer + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES: times STAs go to sleep + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION: STAs' total sleep time + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ: number of probe + * requests received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT: number of other mgmt + * frames received + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME: Percentage of idle time + * there is no TX, nor RX, nor interference. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME: percentage of time + * transmitting packets. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_TIME: percentage of time + * for receiving. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY: percentage of time + * interference detected. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD: percentage of time + * receiving packets with errors. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD: percentage of time + * TX no-ACK. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL: percentage of time + * the chip is unable to work in normal conditions. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME: percentage of time + * receiving packets in current BSS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME: percentage of time + * receiving packets not in current BSS. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM: number of antennas + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL: + * This is a container for per antenna signal stats. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR: per antenna SNR value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF: per antenna NF value + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_RSSI_BEACON: RSSI of beacon + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_SNR_BEACON: SNR of beacon + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_REPORT_TIME: u64 + * Absolute timestamp from 1970/1/1, unit in ms. After receiving the + * message, user layer APP could call gettimeofday to get another + * timestamp and calculate transfer delay for the message. + * @QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MEASUREMENT_TIME: u32 + * Real period for this measurement, unit in us. + */ +enum qca_wlan_vendor_attr_ll_stats_ext { + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_INVALID = 0, + + /* Attributes for configurations */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_PERIOD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CFG_THRESHOLD, + + /* Peer STA power state change */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_CHG, + + /* TX failure event */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NUM_MSDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_STATUS, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_STATE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_MAC_ADDRESS, + + /* MAC counters */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_GLOBAL, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_EVENT_MODE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_ID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ID, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_SIGNAL_BITMAP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CHANNEL_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_CCA_BSS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER, + + /* Sub-attributes for PEER_AC_TX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MSDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_MPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_PPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DROP_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_RETRY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_ACK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_NO_BACK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_AGGR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_SUCC_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_FAIL_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_DELAY_ARRAY_SIZE, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_DELAY, + + /* Sub-attributes for PEER_AC_RX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PPDU_BYTES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_LOST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_RETRY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DUP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MPDU_DISCARD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MCS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_AGGR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_TIMES, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_PS_DURATION, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_PROBE_REQ, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_MGMT, + + /* Sub-attributes for CCA_BSS */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IDLE_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BUSY, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_RX_BAD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_TX_BAD, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_NO_AVAIL, + + /* sub-attribute for BSS_RX_TIME */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IN_BSS_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_OUT_BSS_TIME, + + /* Sub-attributes for PEER_SIGNAL */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_ANT_NUM, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_PEER_SIGNAL, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_SNR, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_ANT_NF, + + /* Sub-attributes for IFACE_BSS */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_RSSI_BEACON, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_IFACE_SNR_BEACON, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_REPORT_TIME, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MEASUREMENT_TIME, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST - 1 +}; + +/* Attributes for FTM commands and events */ + +/** + * enum qca_wlan_vendor_attr_loc_capa - Indoor location capabilities + * + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS: Various flags. See + * enum qca_wlan_vendor_attr_loc_capa_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS: Maximum number + * of measurement sessions that can run concurrently. + * Default is one session (no session concurrency). + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS: The total number of unique + * peers that are supported in running sessions. For example, + * if the value is 8 and maximum number of sessions is 2, you can + * have one session with 8 unique peers, or 2 sessions with 4 unique + * peers each, and so on. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP: Maximum number + * of bursts per peer, as an exponent (2^value). Default is 0, + * meaning no multi-burst support. + * @QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST: Maximum number + * of measurement exchanges allowed in a single burst. + * @QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES: Supported AOA measurement + * types. A bit mask (unsigned 32 bit value), each bit corresponds + * to an AOA type as defined by enum qca_vendor_attr_aoa_type. + */ +enum qca_wlan_vendor_attr_loc_capa { + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_INVALID, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_SESSIONS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_PEERS, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_NUM_BURSTS_EXP, + QCA_WLAN_VENDOR_ATTR_FTM_CAPA_MAX_MEAS_PER_BURST, + QCA_WLAN_VENDOR_ATTR_AOA_CAPA_SUPPORTED_TYPES, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_MAX = + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_loc_capa_flags: Indoor location capability flags + * + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER: Set if driver + * can be configured as an FTM responder (for example, an AP that + * services FTM requests). QCA_NL80211_VENDOR_SUBCMD_FTM_CFG_RESPONDER + * will be supported if set. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR: Set if driver + * can run FTM sessions. QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION + * will be supported if set. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP: Set if FTM responder + * supports immediate (ASAP) response. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA: Set if driver supports standalone + * AOA measurement using QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS. + * @QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM: Set if driver supports + * requesting AOA measurements as part of an FTM session. + */ +enum qca_wlan_vendor_attr_loc_capa_flags { + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_RESPONDER = 1 << 0, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_FTM_INITIATOR = 1 << 1, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_ASAP = 1 << 2, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA = 1 << 3, + QCA_WLAN_VENDOR_ATTR_LOC_CAPA_FLAG_AOA_IN_FTM = 1 << 4, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_info: Information about + * a single peer in a measurement session. + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR: The MAC address of the peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS: Various flags related + * to measurement. See enum qca_wlan_vendor_attr_ftm_peer_meas_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS: Nested attribute of + * FTM measurement parameters, as specified by IEEE P802.11-REVmc/D7.0 + * 9.4.2.167. See enum qca_wlan_vendor_attr_ftm_meas_param for + * list of supported attributes. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID: Initial token ID for + * secure measurement. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD: Request AOA + * measurement every <value> bursts. If 0 or not specified, + * AOA measurements will be disabled for this peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ: Frequency in MHz where + * the measurement frames are exchanged. Optional; if not + * specified, try to locate the peer in the kernel scan + * results cache and use frequency from there. + */ +enum qca_wlan_vendor_attr_ftm_peer_info { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_PARAMS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AOA_BURST_PERIOD, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_FREQ, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PEER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_meas_flags: Measurement request flags, + * per-peer + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP: If set, request + * immediate (ASAP) response from peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI: If set, request + * LCI report from peer. The LCI report includes the absolute + * location of the peer in "official" coordinates (similar to GPS). + * See IEEE P802.11-REVmc/D7.0, 11.24.6.7 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR: If set, request + * Location civic report from peer. The LCR includes the location + * of the peer in free-form format. See IEEE P802.11-REVmc/D7.0, + * 11.24.6.7 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE: If set, + * request a secure measurement. + * QCA_WLAN_VENDOR_ATTR_FTM_PEER_SECURE_TOKEN_ID must also be provided. + */ +enum qca_wlan_vendor_attr_ftm_peer_meas_flags { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_ASAP = 1 << 0, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCI = 1 << 1, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_LCR = 1 << 2, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_MEAS_FLAG_SECURE = 1 << 3, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_meas_param: Measurement parameters + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST: Number of measurements + * to perform in a single burst. + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP: Number of bursts to + * perform, specified as an exponent (2^value). + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION: Duration of burst + * instance, as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167. + * @QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD: Time between bursts, + * as specified in IEEE P802.11-REVmc/D7.0, 9.4.2.167. Must + * be larger than QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION. + */ +enum qca_wlan_vendor_attr_ftm_meas_param { + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MEAS_PER_BURST, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_NUM_BURSTS_EXP, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_DURATION, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_BURST_PERIOD, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PARAM_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result: Per-peer results + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR: MAC address of the reported + * peer. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS: Status of measurement + * request for this peer. + * See enum qca_wlan_vendor_attr_ftm_peer_result_status. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS: Various flags related + * to measurement results for this peer. + * See enum qca_wlan_vendor_attr_ftm_peer_result_flags. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS: Specified when + * request failed and peer requested not to send an additional request + * for this number of seconds. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI: LCI report when received + * from peer. In the format specified by IEEE P802.11-REVmc/D7.0, + * 9.4.2.22.10. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR: Location civic report when + * received from peer. In the format specified by IEEE P802.11-REVmc/D7.0, + * 9.4.2.22.13. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS: Reported when peer + * overridden some measurement request parameters. See + * enum qca_wlan_vendor_attr_ftm_meas_param. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS: AOA measurement + * for this peer. Same contents as @QCA_WLAN_VENDOR_ATTR_AOA_MEAS_RESULT. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS: Array of measurement + * results. Each entry is a nested attribute defined + * by enum qca_wlan_vendor_attr_ftm_meas. + */ +enum qca_wlan_vendor_attr_ftm_peer_result { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAC_ADDR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAGS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCI, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_LCR, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAMS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AOA_MEAS, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result_status + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK: Request sent ok and results + * will be provided. Peer may have overridden some measurement parameters, + * in which case overridden parameters will be report by + * QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_MEAS_PARAM attribute. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE: Peer is incapable + * of performing the measurement request. No more results will be sent + * for this peer in this session. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED: Peer reported request + * failed, and requested not to send an additional request for number + * of seconds specified by QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_VALUE_SECONDS + * attribute. + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID: Request validation + * failed. Request was not sent over the air. + */ +enum qca_wlan_vendor_attr_ftm_peer_result_status { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_OK, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INCAPABLE, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_FAILED, + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_STATUS_INVALID, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_peer_result_flags: Various flags + * for measurement result, per-peer + * + * @QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE: If set, + * measurement completed for this peer. No more results will be reported + * for this peer in this session. + */ +enum qca_wlan_vendor_attr_ftm_peer_result_flags { + QCA_WLAN_VENDOR_ATTR_FTM_PEER_RES_FLAG_DONE = 1 << 0, +}; + +/** + * enum qca_vendor_attr_loc_session_status: Session completion status code + * + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK: Session completed + * successfully. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED: Session aborted + * by request. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID: Session request + * was invalid and was not started. + * @QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED: Session had an error + * and did not complete normally (for example out of resources). + */ +enum qca_vendor_attr_loc_session_status { + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_OK, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_ABORTED, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_INVALID, + QCA_WLAN_VENDOR_ATTR_LOC_SESSION_STATUS_FAILED, +}; + +/** + * enum qca_wlan_vendor_attr_ftm_meas: Single measurement data + * + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1: Time of departure (TOD) of FTM packet as + * recorded by responder, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2: Time of arrival (TOA) of FTM packet at + * initiator, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3: TOD of ACK packet as recorded by + * initiator, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4: TOA of ACK packet at + * responder, in picoseconds. + * See IEEE P802.11-REVmc/D7.0, 11.24.6.4 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI: RSSI (signal level) as recorded + * during this measurement exchange. Optional and will be provided if + * the hardware can measure it. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR: TOD error reported by + * responder. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR: TOA error reported by + * responder. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR: TOD error measured by + * initiator. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR: TOA error measured by + * initiator. Not always provided. + * See IEEE P802.11-REVmc/D7.0, 9.6.8.33 for more information. + * @QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD: Dummy attribute for padding. + */ +enum qca_wlan_vendor_attr_ftm_meas { + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INVALID, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T1, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T2, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T3, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_T4, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_RSSI, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOD_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_TOA_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOD_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_INITIATOR_TOA_ERR, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_PAD, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_MAX = + QCA_WLAN_VENDOR_ATTR_FTM_MEAS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_aoa_type - AOA measurement type + * + * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE: Phase of the strongest + * CIR (channel impulse response) path for each antenna. + * @QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP: Phase and amplitude + * of the strongest CIR path for each antenna. + */ +enum qca_wlan_vendor_attr_aoa_type { + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE, + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_TOP_CIR_PHASE_AMP, + QCA_WLAN_VENDOR_ATTR_AOA_TYPE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_encryption_test - Attributes to + * validate encryption engine + * + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION: Flag attribute. + * This will be included if the request is for decryption; if not included, + * the request is treated as a request for encryption by default. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER: Unsigned 32-bit value + * indicating the key cipher suite. Takes same values as + * NL80211_ATTR_KEY_CIPHER. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID: Unsigned 8-bit value + * Key Id to be used for encryption + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK: Array of 8-bit values. + * Key (TK) to be used for encryption/decryption + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN: Array of 8-bit values. + * Packet number to be specified for encryption/decryption + * 6 bytes for TKIP/CCMP/GCMP. + * @QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA: Array of 8-bit values + * representing the 802.11 packet (header + payload + FCS) that + * needs to be encrypted/decrypted. + * Encrypted/decrypted response from the driver will also be sent + * to userspace with the same attribute. + */ +enum qca_wlan_vendor_attr_encryption_test { + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_TK, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX = + QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_dmg_rf_sector_type - Type of + * sector for DMG RF sector operations. + * + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_RX: RX sector + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_TX: TX sector + */ +enum qca_wlan_vendor_attr_dmg_rf_sector_type { + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_RX, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_TX, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_TYPE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_fw_state - State of firmware + * + * @QCA_WLAN_VENDOR_ATTR_FW_STATE_ERROR: FW is in bad state + * @QCA_WLAN_VENDOR_ATTR_FW_STATE_ACTIVE: FW is active + */ +enum qca_wlan_vendor_attr_fw_state { + QCA_WLAN_VENDOR_ATTR_FW_STATE_ERROR, + QCA_WLAN_VENDOR_ATTR_FW_STATE_ACTIVE, + QCA_WLAN_VENDOR_ATTR_FW_STATE_MAX +}; + +/** + * BRP antenna limit mode + * + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE: Disable BRP force + * antenna limit, BRP will be performed as usual. + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_EFFECTIVE: Define maximal + * antennas limit. the hardware may use less antennas than the + * maximum limit. + * @QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_FORCE: The hardware will + * use exactly the specified number of antennas for BRP. + */ +enum qca_wlan_vendor_attr_brp_ant_limit_mode { + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_DISABLE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_EFFECTIVE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_FORCE, + QCA_WLAN_VENDOR_ATTR_BRP_ANT_LIMIT_MODE_MAX +}; + +/** + * enum qca_wlan_vendor_attr_dmg_rf_sector_cfg - Attributes for + * DMG RF sector configuration for a single RF module. + * The values are defined in a compact way which closely matches + * the way it is stored in HW registers. + * The configuration provides values for 32 antennas and 8 distribution + * amplifiers, and together describes the characteristics of the RF + * sector - such as a beam in some direction with some gain. + * + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX: Index + * of RF module for this configuration. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE0: Bit 0 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE1: Bit 1 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE2: Bit 2 of edge + * amplifier gain index. Unsigned 32 bit number containing + * bits for all 32 antennas. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_HI: Phase values + * for first 16 antennas, 2 bits per antenna. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_LO: Phase values + * for last 16 antennas, 2 bits per antenna. + * @QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16: Contains + * DTYPE values (3 bits) for each distribution amplifier, followed + * by X16 switch bits for each distribution amplifier. There are + * total of 8 distribution amplifiers. + */ +enum qca_wlan_vendor_attr_dmg_rf_sector_cfg { + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MODULE_INDEX = 1, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE0 = 2, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE1 = 3, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_ETYPE2 = 4, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_HI = 5, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_PSH_LO = 6, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16 = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_MAX = + QCA_WLAN_VENDOR_ATTR_DMG_RF_SECTOR_CFG_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_set { + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_INVALID = 0, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING = 2, + /* 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_clr { + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_INVALID = 0, + /* Unsigned 32bit bitmap for clearing statistics + * All radio statistics 0x00000001 + * cca_busy_time (within radio statistics) 0x00000002 + * All channel stats (within radio statistics) 0x00000004 + * All scan statistics (within radio statistics) 0x00000008 + * All interface statistics 0x00000010 + * All tx rate statistics (within interface statistics) 0x00000020 + * All ac statistics (with in interface statistics) 0x00000040 + * All contention (min, max, avg) statistics (within ac statisctics) + * 0x00000080. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK = 1, + /* Unsigned 8 bit value: Request to stop statistics collection */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ = 2, + + /* Unsigned 32 bit bitmap: Response from the driver + * for the cleared statistics + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK = 3, + /* Unsigned 8 bit value: Response from driver/firmware + * for the stop request + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP = 4, + /* keep last */ + 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_get { + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_INVALID = 0, + /* Unsigned 32 bit 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 = 1, + /* Unsigned 32 bit value - bit mask to identify what statistics are + * requested for retrieval. + * Radio Statistics 0x00000001 + * Interface Statistics 0x00000020 + * All Peer Statistics 0x00000040 + * Peer Statistics 0x00000080 + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK = 2, + /* 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_results { + QCA_WLAN_VENDOR_ATTR_LL_STATS_INVALID = 0, + /* Unsigned 32bit value. Used by the driver; must match the request id + * provided with the QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET command. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_REQ_ID = 1, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX = 2, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX = 3, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX = 4, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX = 5, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT = 6, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA = 7, + /* Signed 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK = 8, + + /* 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 = 9, + /* Interface MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR = 10, + /* Type = enum wifi_connection_state, e.g., DISCONNECTED, + * AUTHENTICATING, etc. valid for STA, CLI only. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE = 11, + /* Type = enum wifi_roam_state. Roaming state, e.g., IDLE or ACTIVE + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING = 12, + /* Unsigned 32 bit value. WIFI_CAPABILITY_XXX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES = 13, + /* NULL terminated SSID. An array of 33 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID = 14, + /* BSSID. An array of 6 unsigned 8 bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID = 15, + /* Country string advertised by AP. An array of 3 unsigned 8 bit + * values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR = 16, + /* Country string for this association. An array of 3 unsigned 8 bit + * values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR = 17, + + /* 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 = 18, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU = 19, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU = 20, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST = 21, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST = 22, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU = 23, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU = 24, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST = 25, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES = 26, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT = 27, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG = 28, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN = 29, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX = 30, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG = 31, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES = 32, + /* Unsigned 32 bit value. Number of peers */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS = 33, + + /* 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 = 34, + /* MAC addr corresponding to respective peer. An array of 6 unsigned + * 8 bit values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS = 35, + /* Unsigned int 32 bit value representing capabilities corresponding + * to respective peer. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES = 36, + /* Unsigned 32 bit value. Number of rates */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES = 37, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* + * are nested within the rate stat. + */ + + /* Wi-Fi Rate - separate attributes defined for individual fields */ + + /* Unsigned int 8 bit value; 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE = 38, + /* Unsigned int 8 bit value; 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS = 39, + /* Unsigned int 8 bit value; 0:20 MHz, 1:40 MHz, 2:80 MHz, 3:160 MHz */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW = 40, + /* Unsigned int 8 bit value; OFDM/CCK rate code would be as per IEEE Std + * in the units of 0.5 Mbps HT/VHT it would be MCS index + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX = 41, + + /* Unsigned 32 bit value. Bit rate in units of 100 kbps */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE = 42, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_STAT_* could be + * nested within the peer info stats. + */ + + /* Unsigned int 32 bit value. Number of successfully transmitted data + * packets, i.e., with ACK received corresponding to the respective + * rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU = 43, + /* Unsigned int 32 bit value. Number of received data packets + * corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU = 44, + /* Unsigned int 32 bit value. Number of data packet losses, i.e., no ACK + * received corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST = 45, + /* Unsigned int 32 bit value. Total number of data packet retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES = 46, + /* Unsigned int 32 bit value. Total number of short data packet retries + * for the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT = 47, + /* Unsigned int 32 bit value. Total number of long data packet retries + * for the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG = 48, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID = 49, + /* Unsigned 32 bit value. Total number of msecs the radio is awake + * accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME = 50, + /* Unsigned 32 bit value. Total number of msecs the radio is + * transmitting accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME = 51, + /* Unsigned 32 bit value. Total number of msecs the radio is in active + * receive accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME = 52, + /* Unsigned 32 bit 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 = 53, + /* Unsigned 32 bit 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 = 54, + /* Unsigned 32 bit 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 = 55, + /* Unsigned 32 bit 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 = 56, + /* Unsigned 32 bit 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 = 57, + /* Unsigned 32 bit value. Total number of msecs the radio is awake due + * to Hotspot 2.0 scans and GAS exchange accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20 = 58, + /* Unsigned 32 bit value. Number of channels. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS = 59, + + /* 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 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH = 60, + /* Unsigned 32 bit value. Primary 20 MHz channel. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ = 61, + /* Unsigned 32 bit value. Center frequency (MHz) first segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0 = 62, + /* Unsigned 32 bit value. Center frequency (MHz) second segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1 = 63, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_* could be + * nested within the radio stats. + */ + + /* Unsigned int 32 bit value representing total number of msecs the + * radio is awake on that channel accruing over time, corresponding to + * the respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME = 64, + /* Unsigned int 32 bit 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 = 65, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS = 66, + + /* Signifies the nested list of channel attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO = 67, + + /* Signifies the nested list of peer info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO = 68, + + /* Signifies the nested list of rate info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO = 69, + + /* Signifies the nested list of wmm info attributes + * QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_* + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO = 70, + + /* Unsigned 8 bit 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 = 71, + + /* Unsigned 64 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET = 72, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED = 73, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED = 74, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME = 75, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE = 76, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS = 77, + + /* Number of msecs the radio spent in transmitting for each power level + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME_PER_LEVEL = 78, + + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_SUCC_CNT = 79, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RTS_FAIL_CNT = 80, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_SUCC_CNT = 81, + /* Unsigned 32 bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_PPDU_FAIL_CNT = 82, + + /* Unsigned int 32 value. + * Pending MSDUs corresponding to respective AC. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_PENDING_MSDU = 83, + + /* u32 value representing total time in milliseconds for which the radio + * is transmitting on this channel. This attribute will be nested + * within QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_TX_TIME = 84, + /* u32 value representing total time in milliseconds for which the radio + * is receiving all 802.11 frames intended for this device on this + * channel. This attribute will be nested within + * QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85, + /* u8 value representing the channel load percentage. Possible values + * are 0-100. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86, + /* u8 value representing the time slicing duty cycle percentage. + * Possible values are 0-100. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_TS_DUTY_CYCLE = 87, + /* 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, +}; + +enum qca_wlan_vendor_attr_ll_stats_type { + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_INVALID = 0, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO = 1, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE = 2, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS = 3, + + /* keep last */ + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_AFTER_LAST, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_MAX = + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_tdls_configuration - Attributes for + * TDLS configuration to the host driver. + * + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE: Configure the TDLS trigger + * mode in the host driver. enum qca_wlan_vendor_tdls_trigger_mode + * represents the different TDLS trigger modes. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD: Duration (u32) within + * which QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD number + * of packets shall meet the criteria for implicit TDLS setup. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD: Number (u32) of Tx/Rx packets + * within a duration QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD + * to initiate a TDLS setup. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_DISCOVERY_PERIOD: Time (u32) to initiate + * a TDLS Discovery to the peer. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX_DISCOVERY_ATTEMPT: Max number (u32) of + * discovery attempts to know the TDLS capability of the peer. A peer is + * marked as TDLS not capable if there is no response for all the attempts. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT: Represents a duration (u32) + * within which QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD + * number of TX / RX frames meet the criteria for TDLS teardown. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD: Minimum number (u32) + * of Tx/Rx packets within a duration + * QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT to tear down a TDLS link. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_SETUP_RSSI_THRESHOLD: Threshold + * corresponding to the RSSI of the peer below which a TDLS setup is + * triggered. + * @QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TEARDOWN_RSSI_THRESHOLD: Threshold + * corresponding to the RSSI of the peer above which a TDLS teardown is + * triggered. + */ +enum qca_wlan_vendor_attr_tdls_configuration { + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE = 1, + + /* Attributes configuring the TDLS Implicit Trigger */ + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_STATS_PERIOD = 2, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TX_THRESHOLD = 3, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_DISCOVERY_PERIOD = 4, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX_DISCOVERY_ATTEMPT = 5, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_TIMEOUT = 6, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IDLE_PACKET_THRESHOLD = 7, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_SETUP_RSSI_THRESHOLD = 8, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TEARDOWN_RSSI_THRESHOLD = 9, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_tdls_trigger_mode: Represents the TDLS trigger mode in + * the driver + * + * The following are the different values for + * QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE. + * + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: The trigger to initiate/teardown + * the TDLS connection to a respective peer comes from the user space. + * wpa_supplicant provides the commands TDLS_SETUP, TDLS_TEARDOWN, + * TDLS_DISCOVER to do this. + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: Host driver triggers this TDLS + * setup/teardown to the eligible peer once the configured criteria + * (such as TX/RX threshold, RSSI) is met. The attributes + * in QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_IMPLICIT_PARAMS correspond to + * the different configuration criteria for the TDLS trigger from the + * host driver. + * @QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: Enables the driver to trigger + * the TDLS setup / teardown through the implicit mode only to the + * configured MAC addresses (wpa_supplicant, with tdls_external_control=1, + * configures the MAC address through TDLS_SETUP / TDLS_TEARDOWN commands). + * External mode works on top of the implicit mode. Thus the host driver + * is expected to configure in TDLS Implicit mode too to operate in + * External mode. + * Configuring External mode alone without Implicit mode is invalid. + * + * All the above implementations work as expected only when the host driver + * advertises the capability WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP - representing + * that the TDLS message exchange is not internal to the host driver, but + * depends on wpa_supplicant to do the message exchange. + */ +enum qca_wlan_vendor_tdls_trigger_mode { + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT = 1 << 0, + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT = 1 << 1, + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL = 1 << 2, +}; + +/** + * enum qca_vendor_attr_sar_limits_selections - Source of SAR power limits + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0: Select SAR profile #0 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1: Select SAR profile #1 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2: Select SAR profile #2 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3: Select SAR profile #3 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4: Select SAR profile #4 + * that is hard-coded in the Board Data File (BDF). + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE: Do not select any + * source of SAR power limits, thereby disabling the SAR power + * limit feature. + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER: Select the SAR power + * limits configured by %QCA_NL80211_VENDOR_SUBCMD_SET_SAR. + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0: Select the SAR power + * limits version 2.0 configured by %QCA_NL80211_VENDOR_SUBCMD_SET_SAR. + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT in an instance of + * the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor command or in + * the response to an instance of the + * %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS vendor command. + */ +enum qca_vendor_attr_sar_limits_selections { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0 = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1 = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2 = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3 = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4 = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER = 6, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0 = 7, +}; + +/** + * enum qca_vendor_attr_sar_limits_spec_modulations - + * SAR limits specification modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK - + * CCK modulation + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM - + * OFDM modulation + * + * This enumerates the valid set of values that may be supplied for + * attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION in an + * instance of attribute %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC in an + * instance of the %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS vendor + * command or in the response to an instance of the + * %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS vendor command. + */ +enum qca_vendor_attr_sar_limits_spec_modulations { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM = 1, +}; + +/** + * enum qca_vendor_attr_sar_limits - Attributes for SAR power limits + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE: Optional (u32) value to + * select which SAR power limit table should be used. Valid + * values are enumerated in enum + * %qca_vendor_attr_sar_limits_selections. The existing SAR + * power limit selection is unchanged if this attribute is not + * present. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS: Optional (u32) value + * which specifies the number of SAR power limit specifications + * which will follow. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC: Nested array of SAR power + * limit specifications. The number of specifications is + * specified by @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS. Each + * specification contains a set of + * QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_* attributes. A + * specification is uniquely identified by the attributes + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND, + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN, and + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION and always + * contains as a payload the attribute + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT, + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX. + * Either %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT or + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX is + * needed based upon the value of + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND: Optional (u32) value to + * indicate for which band this specification applies. Valid + * values are enumerated in enum %nl80211_band (although not all + * bands may be supported by a given device). If the attribute is + * not supplied then the specification will be applied to all + * supported bands. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN: Optional (u32) value + * to indicate for which antenna chain this specification + * applies, i.e. 1 for chain 1, 2 for chain 2, etc. If the + * attribute is not supplied then the specification will be + * applied to all chains. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION: Optional (u32) + * value to indicate for which modulation scheme this + * specification applies. Valid values are enumerated in enum + * %qca_vendor_attr_sar_limits_spec_modulations. If the attribute + * is not supplied then the specification will be applied to all + * modulation schemes. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT: Required (u32) + * value to specify the actual power limit value in units of 0.5 + * dBm (i.e., a value of 11 represents 5.5 dBm). + * This is required, when %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT is + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER. + * + * @QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX: Required (u32) + * value to indicate SAR V2 indices (0 - 11) to select SAR V2 profiles. + * This is required, when %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT is + * %QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0. + * + * These attributes are used with %QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS + * and %QCA_NL80211_VENDOR_SUBCMD_GET_SAR_LIMITS. + */ +enum qca_vendor_attr_sar_limits { + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE = 1, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS = 2, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC = 3, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND = 4, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN = 5, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION = 6, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT = 7, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX = 8, + + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX = + QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_get_wifi_info: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO sub command. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION: In a request this attribute + * should be set to any U8 value to indicate that the driver version + * should be returned. When enabled in this manner, in a response this + * attribute will contain a string representation of the driver version. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION: In a request this attribute + * should be set to any U8 value to indicate that the firmware version + * should be returned. When enabled in this manner, in a response this + * attribute will contain a string representation of the firmware version. + * + * @QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX: In a request this attribute + * should be set to any U32 value to indicate that the current radio + * index should be returned. When enabled in this manner, in a response + * this attribute will contain a U32 radio index value. + * + */ +enum qca_wlan_vendor_attr_get_wifi_info { + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION = 2, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_AFTER_LAST - 1, +}; + +/* + * enum qca_wlan_vendor_attr_wifi_logger_start: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START sub command. + */ +enum qca_wlan_vendor_attr_wifi_logger_start { + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID = 1, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL = 2, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_GET_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_logger_results { + QCA_WLAN_VENDOR_ATTR_LOGGER_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_LOGGER_RESULTS_REQUEST_ID = 1, + + /* Unsigned 32-bit value; used to indicate the size of memory + * dump to be allocated. + */ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MEMDUMP_SIZE = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_LOGGER_RESULTS_AFTER_LAST - 1, +}; + +/** + * enum qca_scan_freq_list_type: Frequency list types + * + * @QCA_PREFERRED_SCAN_FREQ_LIST: The driver shall use the scan frequency list + * specified with attribute QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST as + * a preferred frequency list for roaming. + * + * @QCA_SPECIFIC_SCAN_FREQ_LIST: The driver shall use the frequency list + * specified with attribute QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST as + * a specific frequency list for roaming. + */ +enum qca_scan_freq_list_type { + QCA_PREFERRED_SCAN_FREQ_LIST = 1, + QCA_SPECIFIC_SCAN_FREQ_LIST = 2, +}; + +/** + * enum qca_vendor_attr_scan_freq_list_scheme: Frequency list scheme + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST: Nested attribute of u32 values + * List of frequencies in MHz to be considered for a roam scan. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_TYPE: Unsigned 32-bit value. + * Type of frequency list scheme being configured/gotten as defined by the + * enum qca_scan_freq_list_type. + */ +enum qca_vendor_attr_scan_freq_list_scheme { + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST = 1, + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_TYPE = 2, + + /* keep last */ + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST, + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_MAX = + QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST_SCHEME_AFTER_LAST - 1, +}; + +/** + * enum qca_roam_scan_scheme: Scan scheme + * + * @QCA_ROAM_SCAN_SCHEME_NO_SCAN: No frequencies specified to scan. + * Indicates the driver to not scan on a Roam Trigger scenario, but + * disconnect. E.g., on a BTM request from the AP the driver/firmware shall + * disconnect from the current connected AP by notifying a failure + * code in the BTM response. + * + * @QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN: Indicates the driver/firmware to + * trigger partial frequency scans. These frequencies are the ones learned + * or maintained by the driver based on the probability of finding the + * BSSIDs in the ESS for which the roaming is triggered. + * + * @QCA_ROAM_SCAN_SCHEME_FULL_SCAN: Indicates the driver/firmware to + * trigger the scan on all the valid frequencies to find better + * candidates to roam. + */ +enum qca_roam_scan_scheme { + QCA_ROAM_SCAN_SCHEME_NO_SCAN = 0, + QCA_ROAM_SCAN_SCHEME_PARTIAL_SCAN = 1, + QCA_ROAM_SCAN_SCHEME_FULL_SCAN = 2, +}; + +/* + * enum qca_vendor_roam_triggers: Bitmap of roaming triggers + * + * @QCA_ROAM_TRIGGER_REASON_PER: Set if the roam has to be triggered based on + * a bad packet error rates (PER). + * @QCA_ROAM_TRIGGER_REASON_BEACON_MISS: Set if the roam has to be triggered + * based on beacon misses from the connected AP. + * @QCA_ROAM_TRIGGER_REASON_POOR_RSSI: Set if the roam has to be triggered + * due to poor RSSI of the connected AP. + * @QCA_ROAM_TRIGGER_REASON_BETTER_RSSI: Set if the roam has to be triggered + * upon finding a BSSID with a better RSSI than the connected BSSID. + * Here the RSSI of the current BSSID need not be poor. + * @QCA_ROAM_TRIGGER_REASON_PERIODIC: Set if the roam has to be triggered + * by triggering a periodic scan to find a better AP to roam. + * @QCA_ROAM_TRIGGER_REASON_DENSE: Set if the roam has to be triggered + * when the connected channel environment is too noisy/congested. + * @QCA_ROAM_TRIGGER_REASON_BTM: Set if the roam has to be triggered + * when BTM Request frame is received from the connected AP. + * @QCA_ROAM_TRIGGER_REASON_BSS_LOAD: Set if the roam has to be triggered + * when the channel utilization is goes above the configured threshold. + * @QCA_ROAM_TRIGGER_REASON_USER_TRIGGER: Set if the roam has to be triggered + * based on the request from the user (space). + * @QCA_ROAM_TRIGGER_REASON_DEAUTH: Set if the roam has to be triggered when + * device receives Deauthentication/Disassociation frame from connected AP. + * @QCA_ROAM_TRIGGER_REASON_IDLE: Set if the roam has to be triggered when the + * device is in idle state (no TX/RX) and suspend mode, if the current RSSI + * is determined to be a poor one. + * @QCA_ROAM_TRIGGER_REASON_TX_FAILURES: Set if the roam has to be triggered + * based on continuous TX Data frame failures to the connected AP. + * @QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN: Set if the roam has to be triggered + * based on the scan results obtained from an external scan (not triggered + * to aim roaming). + * + * Set the corresponding roam trigger reason bit to consider it for roam + * trigger. + * Userspace can set multiple bits and send to the driver. The driver shall + * consider all of them to trigger/initiate a roam scan. + */ +enum qca_vendor_roam_triggers { + QCA_ROAM_TRIGGER_REASON_PER = 1 << 0, + QCA_ROAM_TRIGGER_REASON_BEACON_MISS = 1 << 1, + QCA_ROAM_TRIGGER_REASON_POOR_RSSI = 1 << 2, + QCA_ROAM_TRIGGER_REASON_BETTER_RSSI = 1 << 3, + QCA_ROAM_TRIGGER_REASON_PERIODIC = 1 << 4, + QCA_ROAM_TRIGGER_REASON_DENSE = 1 << 5, + QCA_ROAM_TRIGGER_REASON_BTM = 1 << 6, + QCA_ROAM_TRIGGER_REASON_BSS_LOAD = 1 << 7, + QCA_ROAM_TRIGGER_REASON_USER_TRIGGER = 1 << 8, + QCA_ROAM_TRIGGER_REASON_DEAUTH = 1 << 9, + QCA_ROAM_TRIGGER_REASON_IDLE = 1 << 10, + QCA_ROAM_TRIGGER_REASON_TX_FAILURES = 1 << 11, + QCA_ROAM_TRIGGER_REASON_EXTERNAL_SCAN = 1 << 12, +}; + +/* + * enum qca_vendor_roam_fail_reasons: Defines the various roam + * fail reasons. This enum value is used in + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON attribute. + * + * @QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED: Roam module in the firmware is not + * able to trigger the scan. + * @QCA_ROAM_FAIL_REASON_NO_AP_FOUND: No roamable APs found during roam scan. + * @QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND: No candidate APs found during roam + * scan. + * @QCA_ROAM_FAIL_REASON_HOST: Roam fail due to disconnect issued from host. + * @QCA_ROAM_FAIL_REASON_AUTH_SEND: Unable to send Authentication frame. + * @QCA_ROAM_FAIL_REASON_AUTH_RECV: Received Authentication frame with error + * status code. + * @QCA_ROAM_FAIL_REASON_NO_AUTH_RESP: Authentication frame not received. + * @QCA_ROAM_FAIL_REASON_REASSOC_SEND: Unable to send Reassociation Request + * frame. + * @QCA_ROAM_FAIL_REASON_REASSOC_RECV: Received Reassociation Response frame + * with error status code. + * @QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP: Reassociation Response frame not + * received. + * @QCA_ROAM_FAIL_REASON_SCAN_FAIL: Scan module not able to start scan. + * @QCA_ROAM_FAIL_REASON_AUTH_NO_ACK: No ACK is received for Authentication + * frame. + * @QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP: Authentication frame is dropped + * internally before transmission. + * @QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK: No ACK is received for Reassociation + * Request frame. + * @QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP: Reassociation Request frame is + * dropped internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT: EAPOL-Key M1 is not received and + * times out. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND: Unable to send EAPOL-Key M2 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP: EAPOL-Key M2 frame dropped + * internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK: No ACK is received for EAPOL-Key + * M2 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT: EAPOL-Key M3 frame is not received. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND: Unable to send EAPOL-Key M4 frame. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP: EAPOL-Key M4 frame dropped + * internally. + * @QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK: No ACK is received for EAPOL-Key M4 + * frame. + * @QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS: Roam scan is not + * started for final beacon miss case. + * @QCA_ROAM_FAIL_REASON_DISCONNECT: Deauthentication or Disassociation frame + * received from the AP during roaming handoff. + * @QCA_ROAM_FAIL_REASON_RESUME_ABORT: Firmware roams to the AP when the Apps + * or host is suspended and gives the indication of the last roamed AP only + * when the Apps is resumed. If the Apps is resumed while the roaming is in + * progress, this ongoing roaming is aborted and the last roamed AP is + * indicated to host. + * @QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID: WPA3-SAE invalid PMKID. + * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT: WPA3-SAE pre-authentication times + * out. + * @QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL: WPA3-SAE pre-authentication fails. + */ +enum qca_vendor_roam_fail_reasons { + QCA_ROAM_FAIL_REASON_NONE = 0, + QCA_ROAM_FAIL_REASON_SCAN_NOT_ALLOWED = 1, + QCA_ROAM_FAIL_REASON_NO_AP_FOUND = 2, + QCA_ROAM_FAIL_REASON_NO_CAND_AP_FOUND = 3, + QCA_ROAM_FAIL_REASON_HOST = 4, + QCA_ROAM_FAIL_REASON_AUTH_SEND = 5, + QCA_ROAM_FAIL_REASON_AUTH_RECV = 6, + QCA_ROAM_FAIL_REASON_NO_AUTH_RESP = 7, + QCA_ROAM_FAIL_REASON_REASSOC_SEND = 8, + QCA_ROAM_FAIL_REASON_REASSOC_RECV = 9, + QCA_ROAM_FAIL_REASON_NO_REASSOC_RESP = 10, + QCA_ROAM_FAIL_REASON_SCAN_FAIL = 11, + QCA_ROAM_FAIL_REASON_AUTH_NO_ACK = 12, + QCA_ROAM_FAIL_REASON_AUTH_INTERNAL_DROP = 13, + QCA_ROAM_FAIL_REASON_REASSOC_NO_ACK = 14, + QCA_ROAM_FAIL_REASON_REASSOC_INTERNAL_DROP = 15, + QCA_ROAM_FAIL_REASON_EAPOL_M1_TIMEOUT = 16, + QCA_ROAM_FAIL_REASON_EAPOL_M2_SEND = 17, + QCA_ROAM_FAIL_REASON_EAPOL_M2_INTERNAL_DROP = 18, + QCA_ROAM_FAIL_REASON_EAPOL_M2_NO_ACK = 19, + QCA_ROAM_FAIL_REASON_EAPOL_M3_TIMEOUT = 20, + QCA_ROAM_FAIL_REASON_EAPOL_M4_SEND = 21, + QCA_ROAM_FAIL_REASON_EAPOL_M4_INTERNAL_DROP = 22, + QCA_ROAM_FAIL_REASON_EAPOL_M4_NO_ACK = 23, + QCA_ROAM_FAIL_REASON_NO_SCAN_FOR_FINAL_BEACON_MISS = 24, + QCA_ROAM_FAIL_REASON_DISCONNECT = 25, + QCA_ROAM_FAIL_REASON_RESUME_ABORT = 26, + QCA_ROAM_FAIL_REASON_SAE_INVALID_PMKID = 27, + QCA_ROAM_FAIL_REASON_SAE_PREAUTH_TIMEOUT = 28, + QCA_ROAM_FAIL_REASON_SAE_PREAUTH_FAIL = 29, +}; + +/* + * enum qca_vendor_roam_invoke_fail_reasons: Defines the various roam + * invoke fail reasons. This enum value is used in + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON attribute. + * + * @QCA_ROAM_INVOKE_STATUS_IFACE_INVALID: Invalid interface ID is passed + * in roam invoke command. + * @QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE: Roam offload in firmware is not + * enabled. + * @QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID: Connected AP profile SSID + * length is invalid. + * @QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW: Firmware internal roaming is already + * in progress. + * @QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP: Host sends the Beacon/Probe Response + * of the AP in the roam invoke command to firmware. This reason is sent by the + * firmware when the given AP is configured to be ignored or SSID/security + * does not match. + * @QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL: Roam handoff failed because of + * firmware internal reasons. + * @QCA_ROAM_INVOKE_STATUS_DISALLOW: Roam invoke trigger is not enabled. + * @QCA_ROAM_INVOKE_STATUS_SCAN_FAIL: Scan start fail for roam invoke. + * @QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL: Roam handoff start fail. + * @QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS: Roam invoke parameters are invalid. + * @QCA_ROAM_INVOKE_STATUS_NO_CAND_AP: No candidate AP found to roam to. + * @QCA_ROAM_INVOKE_STATUS_ROAM_FAIL: Roam handoff failed. + */ +enum qca_vendor_roam_invoke_fail_reasons { + QCA_ROAM_INVOKE_STATUS_NONE = 0, + QCA_ROAM_INVOKE_STATUS_IFACE_INVALID = 1, + QCA_ROAM_INVOKE_STATUS_OFFLOAD_DISABLE = 2, + QCA_ROAM_INVOKE_STATUS_AP_SSID_LENGTH_INVALID = 3, + QCA_ROAM_INVOKE_STATUS_ROAM_DISALLOW = 4, + QCA_ROAM_INVOKE_STATUS_NON_ROAMABLE_AP = 5, + QCA_ROAM_INVOKE_STATUS_ROAM_INTERNAL_FAIL = 6, + QCA_ROAM_INVOKE_STATUS_DISALLOW = 7, + QCA_ROAM_INVOKE_STATUS_SCAN_FAIL = 8, + QCA_ROAM_INVOKE_STATUS_START_ROAM_FAIL = 9, + QCA_ROAM_INVOKE_STATUS_INVALID_PARAMS = 10, + QCA_ROAM_INVOKE_STATUS_NO_CAND_AP = 11, + QCA_ROAM_INVOKE_STATUS_ROAM_FAIL = 12, + +}; + +/** + * enum qca_vendor_attr_roam_candidate_selection_criteria: + * + * Each attribute carries a weightage in percentage (%). + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_RSSI: Unsigned 8-bit value. + * Represents the weightage to be given for the RSSI selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE: Unsigned 8-bit value. + * Represents the weightage to be given for the rate selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BW: Unsigned 8-bit value. + * Represents the weightage to be given for the band width selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BAND: Unsigned 8-bit value. + * Represents the weightage to be given for the band selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_NSS: Unsigned 8-bit value. + * Represents the weightage to be given for the NSS selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_CHAN_CONGESTION: Unsigned 8-bit value. + * Represents the weightage to be given for the channel congestion + * selection criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BEAMFORMING: Unsigned 8-bit value. + * Represents the weightage to be given for the beamforming selection + * criteria among other parameters. + * + * @QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_OCE_WAN: Unsigned 8-bit value. + * Represents the weightage to be given for the OCE selection + * criteria among other parameters. + */ +enum qca_vendor_attr_roam_candidate_selection_criteria { + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_RSSI = 1, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE = 2, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BW = 3, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BAND = 4, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_NSS = 5, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_CHAN_CONGESTION = 6, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_BEAMFORMING = 7, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_SCORE_OCE_WAN = 8, + + /* keep last */ + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_AFTER_LAST, + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_MAX = + QCA_ATTR_ROAM_CAND_SEL_CRITERIA_RATE_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_roam_control - Attributes to carry roam configuration + * The following attributes are used to set/get/clear the respective + * configurations to/from the driver. + * For the get, the attribute for the configuration to be queried shall + * carry any of its acceptable values to the driver. In return, the driver + * shall send the configured values within the same attribute to the user + * space. + * + * @QCA_ATTR_ROAM_CONTROL_ENABLE: Unsigned 8-bit value. + * Signifies to enable/disable roam control in driver. + * 1-enable, 0-disable + * Enable: Mandates the driver to do the further roams using the + * configuration parameters set through + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET. + * Disable: Disables the driver/firmware roaming triggered through + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET. Further roaming is + * expected to continue with the default configurations. + * + * @QCA_ATTR_ROAM_CONTROL_STATUS: Unsigned 8-bit value. + * This is used along with QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET. + * Roam control status is obtained through this attribute. + * + * @QCA_ATTR_ROAM_CONTROL_CLEAR_ALL: Flag attribute to indicate the + * complete config set through QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET + * is to be cleared in the driver. + * This is used along with QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR + * and shall be ignored if used with other sub commands. + * If this attribute is specified along with subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR, the driver shall ignore + * all other attributes, if there are any. + * If this attribute is not specified when the subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR is sent, the driver shall + * clear the data corresponding to the attributes specified. + * + * @QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME: Nested attribute to carry the + * list of frequencies and its type, represented by + * enum qca_vendor_attr_scan_freq_list_scheme. + * Frequency list and its type are mandatory for this attribute to set + * the frequencies. + * Frequency type is mandatory for this attribute to get the frequencies + * and the frequency list is obtained through + * QCA_ATTR_ROAM_CONTROL_SCAN_FREQ_LIST. + * Frequency list type is mandatory for this attribute to clear the + * frequencies. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD: Unsigned 32-bit value. + * Carries the value of scan period in seconds to set. + * The value of scan period is obtained with the same attribute for get. + * Clears the scan period in the driver when specified with clear command. + * Scan period is the idle time in seconds between each subsequent + * channel scans. + * + * @QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD: Unsigned 32-bit value. + * Carries the value of full scan period in seconds to set. + * The value of full scan period is obtained with the same attribute for + * get. + * Clears the full scan period in the driver when specified with clear + * command. Full scan period is the idle period in seconds between two + * successive full channel roam scans. + * + * @QCA_ATTR_ROAM_CONTROL_TRIGGERS: Unsigned 32-bit value. + * Carries a bitmap of the roam triggers specified in + * enum qca_vendor_roam_triggers. + * The driver shall enable roaming by enabling corresponding roam triggers + * based on the trigger bits sent with this attribute. + * If this attribute is not configured, the driver shall proceed with + * default behavior. + * The bitmap configured is obtained with the same attribute for get. + * Clears the bitmap configured in driver when specified with clear + * command. + * + * @QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA: Nested attribute signifying the + * weightage in percentage (%) to be given for each selection criteria. + * Different roam candidate selection criteria are represented by + * enum qca_vendor_attr_roam_candidate_selection_criteria. + * The driver shall select the roam candidate based on corresponding + * candidate selection scores sent. + * + * An empty nested attribute is used to indicate that no specific + * preference score/criteria is configured (i.e., to disable this mechanism + * in the set case and to show that the mechanism is disabled in the get + * case). + * + * Userspace can send multiple attributes out of this enum to the driver. + * Since this attribute represents the weight/percentage of preference for + * the respective selection criteria, it is preferred to configure 100% + * total weightage. The value in each attribute or cumulative weight of the + * values in all the nested attributes should not exceed 100%. The driver + * shall reject such configuration. + * + * If the weights configured through this attribute are less than 100%, + * the driver shall honor the weights (x%) passed for the corresponding + * selection criteria and choose/distribute rest of the weight (100-x)% + * for the other selection criteria, based on its internal logic. + * + * The selection criteria configured is obtained with the same + * attribute for get. + * + * Clears the selection criteria configured in the driver when specified + * with clear command. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME: Unsigned 32-bit value. + * Represents value of the scan frequency scheme from enum + * qca_roam_scan_scheme. + * It's an optional attribute. If this attribute is not configured, the + * driver shall proceed with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD: Signed 32-bit value in dBm, + * signifying the RSSI threshold of the current connected AP, indicating + * the driver to trigger roam only when the current connected AP's RSSI + * is less than this threshold. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD: Signed 32-bit value in dBm, + * signifying the RSSI threshold of the candidate AP, indicating + * the driver to trigger roam only to the candidate AP with RSSI + * better than this threshold. If RSSI thresholds for candidate APs found + * in the 2.4 GHz, 5 GHz, and 6 GHz bands are configured separately using + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ, + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ, and/or + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ, those values will + * take precedence over the value configured using the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute. + * + * @QCA_ATTR_ROAM_CONTROL_USER_REASON: Unsigned 32-bit value. Represents the + * user defined reason code to be sent to the AP in response to AP's + * request to trigger the roam if the roaming cannot be triggered. + * Applies to all the scenarios of AP assisted roaming (e.g., BTM). + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS: Unsigned 32-bit value. + * Carries a bitmap of the roam triggers specified in + * enum qca_vendor_roam_triggers. + * Represents the roam triggers for which the specific scan scheme from + * enum qca_roam_scan_scheme has to be applied. + * It's an optional attribute. If this attribute is not configured, but + * QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is specified, the scan scheme + * specified through QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME is applicable for + * all the roams. + * If both QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME and + * QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS are not specified, the + * driver shall proceed with the default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ: Signed 32-bit value + * in dBm, signifying the RSSI threshold of the candidate AP found in the + * 2.4 GHz band. The driver/firmware shall trigger roaming to the candidate + * AP found in the 2.4 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ: Signed 32-bit value in + * dBm, signifying the RSSI threshold of the candidate AP found in the 5 + * GHz band. The driver/firmware shall trigger roaming to the candidate AP + * found in the 5 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by tge + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ: Signed 32-bit value in + * dBm, signifying the RSSI threshold of the candidate AP found in the 6 + * GHz band. The driver/firmware shall trigger roaming to the candidate AP + * found in the 6 GHz band only if its RSSI value is better than this + * threshold. Optional attribute. If this attribute is not included, the + * threshold value specified by the + * QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD attribute shall be used. + * + * @QCA_ATTR_ROAM_CONTROL_BAND_MASK: Unsigned 32-bit value. + * Carries bitmask value of bits from &enum qca_set_band and represents + * all the bands in which roaming is allowed. The configuration is valid + * until next disconnection. If this attribute is not present, the + * existing configuration shall be used. By default, roaming is allowed on + * all bands supported by the local device. When the value is set to + * %QCA_SETBAND_AUTO, all supported bands shall be enabled. + * + * @QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for active channels in the 2.4/5 GHz + * bands. If this attribute is not configured, the driver shall proceed + * with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for passive channels in the 5 GHz + * band. If this attribute is not configured, the driver shall proceed with + * default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME: u16 value in milliseconds. + * Optional parameter. The minimum duration to stay on the connected AP + * channel during the channel scanning. If this attribute is not + * configured, the driver shall proceed with default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME: u16 value in milliseconds. + * Optional parameter. The maximum duration for which the radio can scan + * foreign channels consecutively without coming back to home channel. If + * this attribute is not configured, the driver shall proceed with default + * behavior. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for 6G Preferred Scanning Channels. + * If this attribute is not configured, the driver shall proceed with + * default behavior. + * + * @QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME: u16 value in milliseconds. + * Optional parameter. Scan dwell time for 6G Non Preferred Scanning + * Channels. If this attribute is not configured, the driver shall proceed + * with default behavior. + */ +enum qca_vendor_attr_roam_control { + QCA_ATTR_ROAM_CONTROL_ENABLE = 1, + QCA_ATTR_ROAM_CONTROL_STATUS = 2, + QCA_ATTR_ROAM_CONTROL_CLEAR_ALL = 3, + QCA_ATTR_ROAM_CONTROL_FREQ_LIST_SCHEME= 4, + QCA_ATTR_ROAM_CONTROL_SCAN_PERIOD = 5, + QCA_ATTR_ROAM_CONTROL_FULL_SCAN_PERIOD = 6, + QCA_ATTR_ROAM_CONTROL_TRIGGERS = 7, + QCA_ATTR_ROAM_CONTROL_SELECTION_CRITERIA = 8, + QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME = 9, + QCA_ATTR_ROAM_CONTROL_CONNECTED_RSSI_THRESHOLD = 10, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD = 11, + QCA_ATTR_ROAM_CONTROL_USER_REASON = 12, + QCA_ATTR_ROAM_CONTROL_SCAN_SCHEME_TRIGGERS = 13, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_2P4GHZ = 14, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_5GHZ = 15, + QCA_ATTR_ROAM_CONTROL_CANDIDATE_RSSI_THRESHOLD_6GHZ = 16, + QCA_ATTR_ROAM_CONTROL_BAND_MASK = 17, + QCA_ATTR_ROAM_CONTROL_ACTIVE_CH_DWELL_TIME = 18, + QCA_ATTR_ROAM_CONTROL_PASSIVE_CH_DWELL_TIME = 19, + QCA_ATTR_ROAM_CONTROL_HOME_CHANNEL_TIME = 20, + QCA_ATTR_ROAM_CONTROL_MAXIMUM_AWAY_TIME = 21, + QCA_ATTR_ROAM_CONTROL_SCAN_6G_PSC_DWELL_TIME = 22, + QCA_ATTR_ROAM_CONTROL_SCAN_6G_NON_PSC_DWELL_TIME = 23, + + /* keep last */ + QCA_ATTR_ROAM_CONTROL_AFTER_LAST, + QCA_ATTR_ROAM_CONTROL_MAX = + QCA_ATTR_ROAM_CONTROL_AFTER_LAST - 1, +}; + +/* + * enum qca_wlan_vendor_attr_roaming_config_params: Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_ROAM sub command. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD: Unsigned 32-bit value. + * Represents the different roam sub commands referred by + * enum qca_wlan_vendor_roaming_subcmd. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID: Unsigned 32-bit value. + * Represents the Request ID for the specific set of commands. + * This also helps to map specific set of commands to the respective + * ID / client. e.g., helps to identify the user entity configuring the + * ignored BSSIDs and accordingly clear the respective ones with the + * matching ID. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS: Unsigned + * 32-bit value. Represents the number of allowlist SSIDs configured. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST: Nested attribute + * to carry the list of allowlist SSIDs. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID: SSID (binary attribute, + * 0..32 octets). Represents the allow list SSID. Allowlist SSIDs + * represent the list of SSIDs to which the firmware/driver can consider + * to roam to. + * + * The following PARAM_A_BAND_XX attributes are applied to 5GHz BSSIDs when + * comparing with a 2.4GHz BSSID. They are not applied when comparing two + * 5GHz BSSIDs.The following attributes are set through the Roaming SUBCMD - + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD: Signed 32-bit + * value, RSSI threshold above which 5GHz RSSI is favored. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD: Signed 32-bit + * value, RSSI threshold below which 5GHz RSSI is penalized. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR: Unsigned 32-bit + * value, factor by which 5GHz RSSI is boosted. + * boost=(RSSI_measured-5GHz_boost_threshold)*5GHz_boost_factor + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR: Unsigned 32-bit + * value, factor by which 5GHz RSSI is penalized. + * penalty=(5GHz_penalty_threshold-RSSI_measured)*5GHz_penalty_factor + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST: Unsigned 32-bit + * value, maximum boost that can be applied to a 5GHz RSSI. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS: Unsigned 32-bit + * value, boost applied to current BSSID to ensure the currently + * associated BSSID is favored so as to prevent ping-pong situations. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER: Signed 32-bit + * value, RSSI below which "Alert" roam is enabled. + * "Alert" mode roaming - firmware is "urgently" hunting for another BSSID + * because the RSSI is low, or because many successive beacons have been + * lost or other bad link conditions. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE: Unsigned 32-bit + * value. 1-Enable, 0-Disable. Represents "Lazy" mode, where + * firmware is hunting for a better BSSID or allow listed SSID even though + * the RSSI of the link is good. The parameters enabling the roaming are + * configured through the PARAM_A_BAND_XX attrbutes. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS: Nested attribute, + * represents the BSSIDs preferred over others while evaluating them + * for the roaming. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID: Unsigned + * 32-bit value. Represents the number of preferred BSSIDs set. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID: 6-byte MAC + * address representing the BSSID to be preferred. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER: Signed + * 32-bit value, representing the modifier to be applied to the RSSI of + * the BSSID for the purpose of comparing it with other roam candidate. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS: Nested attribute, + * represents the BSSIDs to get ignored for roaming. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID: Unsigned + * 32-bit value, represents the number of ignored BSSIDs. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID: 6-byte MAC + * address representing the ignored BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT: Flag attribute, + * indicates this request to ignore the BSSID as a hint to the driver. The + * driver can select this BSSID in the worst case (when no other BSSIDs are + * better). + * + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL: Nested attribute to + * set/get/clear the roam control config as + * defined @enum qca_vendor_attr_roam_control. + */ +enum qca_wlan_vendor_attr_roaming_config_params { + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD = 1, + QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID = 2, + + /* Attributes for wifi_set_ssid_allow_list */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS = 3, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST = 4, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID = 5, + + /* Attributes for set_roam_params */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD = 6, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD = 7, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR = 8, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR = 9, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST = 10, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS = 11, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER = 12, + + /* Attribute for set_lazy_roam */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE = 13, + + /* Attribute for set_lazy_roam with preferences */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS = 14, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID = 15, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID = 16, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER = 17, + + /* Attribute for setting ignored BSSID parameters */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20, + /* Flag attribute indicates this entry as a hint */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT = 21, + + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL = 22, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST - 1, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST +#define QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID \ + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID + +/* + * enum qca_wlan_vendor_roaming_subcmd: Referred by + * QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST: Sub command to + * configure the allow list SSIDs. These are configured through + * the following attributes. + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_NUM_NETWORKS, + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID_LIST, + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALLOW_LIST_SSID + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS: Sub command to + * configure the Roam params. These parameters are evaluated on the GScan + * results. Refers the attributes PARAM_A_BAND_XX above to configure the + * params. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM: Sets the Lazy roam. Uses + * the attribute QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE + * to enable/disable Lazy roam. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS: Sets the BSSID + * preference. Contains the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS to set the BSSID + * preference. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID: Sets the list of BSSIDs + * to ignore in roaming decision. Uses + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS to set the list. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET: Command to set the + * roam control config to the driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET: Command to obtain the + * roam control config from driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * For the get, the attribute for the configuration to be queried shall + * carry any of its acceptable value to the driver. In return, the driver + * shall send the configured values within the same attribute to the user + * space. + * + * @QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR: Command to clear the + * roam control config in the driver with the attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_CONTROL. + * The driver shall continue with its default roaming behavior when data + * corresponding to an attribute is cleared. + */ +enum qca_wlan_vendor_roaming_subcmd { + QCA_WLAN_VENDOR_ROAMING_SUBCMD_INVALID = 0, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST = 1, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_GSCAN_ROAM_PARAMS = 2, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_LAZY_ROAM = 3, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PREFS = 4, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BSSID_PARAMS = 5, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID = 6, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_SET = 7, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_GET = 8, + QCA_WLAN_VENDOR_ROAMING_SUBCMD_CONTROL_CLEAR = 9, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_WHITE_LIST \ + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SSID_ALLOW_LIST +#define QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_BLACKLIST_BSSID \ + QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID + +enum qca_wlan_vendor_attr_gscan_config_params { + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0, + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID = 1, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_VALID_CHANNELS sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND + = 2, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS + = 3, + + /* Attributes for input params used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_START sub command. + */ + + /* Unsigned 32-bit value; channel frequency */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CHANNEL = 4, + /* Unsigned 32-bit value; dwell time in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_DWELL_TIME = 5, + /* Unsigned 8-bit value; 0: active; 1: passive; N/A for DFS */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_PASSIVE = 6, + /* Unsigned 8-bit value; channel class */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_CLASS = 7, + + /* Unsigned 8-bit value; bucket index, 0 based */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_INDEX = 8, + /* Unsigned 8-bit value; band. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BAND = 9, + /* Unsigned 32-bit value; desired period, in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_PERIOD = 10, + /* Unsigned 8-bit value; report events semantics. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_REPORT_EVENTS = 11, + /* Unsigned 32-bit value. Followed by a nested array of + * GSCAN_CHANNEL_SPEC_* attributes. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS = 12, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CHANNEL_SPEC = 13, + + /* Unsigned 32-bit value; base timer period in ms. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_BASE_PERIOD = 14, + /* 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_GSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN = 15, + /* Unsigned 8-bit value; in %, when scan buffer is this much full, wake + * up AP. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT + = 16, + + /* Unsigned 8-bit value; number of scan bucket specs; followed by a + * nested array of_GSCAN_BUCKET_SPEC_* attributes and values. The size + * of the array is determined by NUM_BUCKETS. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS = 17, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC = 18, + + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH + = 19, + /* Unsigned 32-bit value; maximum number of results to be returned. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX + = 20, + + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_BSSID = 21, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_LOW = 22, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH = 23, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_CHANNEL = 24, + + /* 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_GSCAN_BSSID_HOTLIST_PARAMS_NUM_AP = 25, + + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM_* attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_AP_THRESHOLD_PARAM = 26, + + /* Unsigned 32-bit value; number of samples for averaging RSSI. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE + = 27, + /* Unsigned 32-bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE + = 28, + /* Unsigned 32-bit value; number of APs breaching threshold. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING = 29, + /* Unsigned 32-bit value; number of APs. Followed by an array of + * AP_THRESHOLD_PARAM attributes. Size of the array is NUM_AP. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP = 30, + /* Unsigned 32-bit value; number of samples to confirm AP loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE + = 31, + /* Unsigned 32-bit value. If max_period is non zero or different than + * period, then this bucket is an exponential backoff bucket. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_MAX_PERIOD = 32, + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_BASE = 33, + /* Unsigned 32-bit value. For exponential back off bucket, number of + * scans to perform for a given period. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_BUCKET_SPEC_STEP_COUNT = 34, + /* Unsigned 8-bit value; in number of scans, wake up AP after these + * many scans. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS + = 35, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SET_SSID_HOTLIST sub command. + */ + /* Unsigned 3-2bit value; number of samples to confirm SSID loss. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE + = 36, + /* Number of hotlist SSIDs as unsigned 32-bit value, followed by a + * nested array of SSID_THRESHOLD_PARAM_* attributes and values. The + * size of the array is determined by NUM_SSID. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_NUM_SSID = 37, + /* Array of QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_* + * attributes. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_HOTLIST_PARAMS_NUM_SSID + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM = 38, + + /* An array of 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_SSID = 39, + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_BAND = 40, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW = 41, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH = 42, + /* Unsigned 32-bit value; a bitmask with additional gscan config flag. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CONFIGURATION_FLAGS = 43, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_GSCAN_SUBCMD_CONFIG_PARAM_AFTER_LAST - 1, +}; + +enum qca_wlan_vendor_attr_gscan_results { + QCA_WLAN_VENDOR_ATTR_GSCAN_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_GSCAN_RESULTS_REQUEST_ID = 1, + + /* Unsigned 32-bit value; used to indicate the status response from + * firmware/driver for the vendor sub-command. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_STATUS = 2, + + /* GSCAN Valid Channels attributes */ + /* Unsigned 32bit value; followed by a nested array of CHANNELS. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_CHANNELS = 3, + /* An array of NUM_CHANNELS x unsigned 32-bit value integers + * representing channel numbers. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CHANNELS = 4, + + /* GSCAN Capabilities attributes */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE = 5, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS = 6, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN + = 7, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE + = 8, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD + = 9, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS = 10, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS + = 11, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES + = 12, + + /* GSCAN Attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_RESULTS_AVAILABLE sub-command. + */ + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE = 13, + + /* GSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_FULL_SCAN_RESULT sub-command. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_* + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST = 14, + + /* Unsigned 64-bit value; age of sample at the time of retrieval */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_TIME_STAMP = 15, + /* 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_SSID = 16, + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BSSID = 17, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CHANNEL = 18, + /* Signed 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RSSI = 19, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT = 20, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_RTT_SD = 21, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD = 22, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_CAPABILITY = 23, + /* Unsigned 32-bit value; size of the IE DATA blob */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_IE_LENGTH = 24, + /* 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_GSCAN_RESULTS_SCAN_RESULT_IE_DATA = 25, + + /* Unsigned 8-bit value; set by driver to indicate more scan results are + * available. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_RESULT_MORE_DATA = 26, + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SCAN_EVENT sub-command. + */ + /* Unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_TYPE = 27, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SCAN_EVENT_STATUS = 28, + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_HOTLIST_AP_FOUND sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of results. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the + * list of results. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_SIGNIFICANT_CHANGE sub-command. + */ + /* An array of 6 x unsigned 8-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID = 29, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL + = 30, + /* Unsigned 32-bit value. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI + = 31, + /* 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_GSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST + = 32, + + /* GSCAN attributes used with + * QCA_NL80211_VENDOR_SUBCMD_GSCAN_GET_CACHED_RESULTS sub-command. + */ + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of gscan cached results returned. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST to indicate + * the list of gscan cached results. + */ + + /* An array of NUM_RESULTS_AVAILABLE x + * QCA_NL80211_VENDOR_ATTR_GSCAN_CACHED_RESULTS_* + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_LIST = 33, + /* Unsigned 32-bit value; a unique identifier for the scan unit. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_SCAN_ID = 34, + /* Unsigned 32-bit value; a bitmask w/additional information about scan. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_CACHED_RESULTS_FLAGS = 35, + /* Use attr QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE + * to indicate number of wifi scan results/bssids retrieved by the scan. + * Also, use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the + * list of wifi scan results returned for each cached result block. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_NETWORK_FOUND sub-command. + */ + /* Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE for + * number of results. + * Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each + * wifi_passpoint_match_result block. + * Array size: QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_NUM_RESULTS_AVAILABLE. + */ + + /* GSCAN attributes for + * QCA_NL80211_VENDOR_SUBCMD_PNO_PASSPOINT_NETWORK_FOUND sub-command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES + = 36, + /* A nested array of + * QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_* + * attributes. Array size = + * *_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_NETWORK_FOUND_NUM_MATCHES. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_RESULT_LIST = 37, + + /* Unsigned 32-bit value; network block id for the matched network */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ID = 38, + /* Use QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_LIST to indicate the nested + * list of wifi scan results returned for each + * wifi_passpoint_match_result block. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP_LEN = 39, + /* An array size of PASSPOINT_MATCH_ANQP_LEN of unsigned 8-bit values; + * ANQP data in the information_element format. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_PNO_RESULTS_PASSPOINT_MATCH_ANQP = 40, + + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS = 41, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS = 42, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_EPNO_NETS_BY_SSID + = 43, + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID + = 44, + + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_BUCKETS_SCANNED = 45, + + /* Unsigned 32-bit value; a GSCAN Capabilities attribute. + * This is used to limit the maximum number of BSSIDs while sending + * the vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM with subcmd + * QCA_WLAN_VENDOR_ROAMING_SUBCMD_SET_DENYLIST_BSSID and attribute + * QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID. + */ + QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID = 46, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_MAX = + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_AFTER_LAST - 1, +}; + +/* old names for API compatibility */ +#define QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_WHITELISTED_SSID \ + QCA_WLAN_VENDOR_ATTR_GSCAN_RESULTS_CAPABILITIES_MAX_NUM_ALLOWLISTED_SSID +#define QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_BLACKLISTED_BSSID \ + QCA_WLAN_VENDOR_ATTR_GSCAN_MAX_NUM_DENYLISTED_BSSID + +enum qca_wlan_vendor_attr_pno_config_params { + QCA_WLAN_VENDOR_ATTR_PNO_INVALID = 0, + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_PNO_SET_PASSPOINT_LIST sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM = 1, + /* Array of nested QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_* + * attributes. Array size = + * QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NETWORK_ARRAY = 2, + + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID = 3, + /* An array of 256 x unsigned 8-bit value; NULL terminated UTF-8 encoded + * realm, 0 if unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_REALM = 4, + /* An array of 16 x unsigned 32-bit value; roaming consortium ids to + * match, 0 if unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_CNSRTM_ID = 5, + /* An array of 6 x unsigned 8-bit value; MCC/MNC combination, 0s if + * unspecified. + */ + QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ROAM_PLMN = 6, + + /* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_PNO_SET_LIST sub command. + */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS = 7, + /* Array of nested + * QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_* + * attributes. Array size = + * QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST = 8, + /* An array of 33 x unsigned 8-bit value; NULL terminated SSID */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID = 9, + /* Signed 8-bit value; threshold for considering this SSID as found, + * required granularity for this threshold is 4 dBm to 8 dBm. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_RSSI_THRESHOLD + = 10, + /* Unsigned 8-bit value; WIFI_PNO_FLAG_XXX */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS = 11, + /* Unsigned 8-bit value; auth bit field for matching WPA IE */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT = 12, + /* Unsigned 8-bit to indicate ePNO type; + * It takes values from qca_wlan_epno_type + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_TYPE = 13, + + /* Nested attribute to send the channel list */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_CHANNEL_LIST = 14, + + /* Unsigned 32-bit value; indicates the interval between PNO scan + * cycles in msec. + */ + QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_SCAN_INTERVAL = 15, + QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI = 16, + QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI = 17, + QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX = 18, + QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS = 19, + QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS = 20, + QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS = 21, + QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS = 22, + /* Unsigned 32-bit value, representing the PNO Request ID */ + QCA_WLAN_VENDOR_ATTR_PNO_CONFIG_REQUEST_ID = 23, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PNO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PNO_MAX = + QCA_WLAN_VENDOR_ATTR_PNO_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_acs_select_reason: This represents the different reasons why + * the ACS has to be triggered. These values are used by + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON and + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON + */ +enum qca_wlan_vendor_acs_select_reason { + /* Represents the reason that the ACS triggered during the AP start */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT, + /* Represents the reason that DFS found with the current channel */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS, + /* Represents the reason that LTE co-exist in the current band. */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX, + /* Represents the reason that generic, uncategorized interference has + * been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_GENERIC_INTERFERENCE, + /* Represents the reason that excessive 802.11 interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_80211_INTERFERENCE, + /* Represents the reason that generic Continuous Wave (CW) interference + * has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_CW_INTERFERENCE, + /* Represents the reason that Microwave Oven (MWO) interference has been + * found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_MWO_INTERFERENCE, + /* Represents the reason that generic Frequency-Hopping Spread Spectrum + * (FHSS) interference has been found in the current channel. This may + * include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_FHSS_INTERFERENCE, + /* Represents the reason that non-802.11 generic Frequency-Hopping + * Spread Spectrum (FHSS) interference has been found in the current + * channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_FHSS_INTERFERENCE, + /* Represents the reason that generic Wideband (WB) interference has + * been found in the current channel. This may include 802.11 waveforms. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_WB_INTERFERENCE, + /* Represents the reason that non-802.11 generic Wideband (WB) + * interference has been found in the current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_NON_80211_WB_INTERFERENCE, + /* Represents the reason that Jammer interference has been found in the + * current channel. + */ + QCA_WLAN_VENDOR_ACS_SELECT_REASON_JAMMER_INTERFERENCE, +}; + +/** + * qca_wlan_vendor_attr_external_acs_policy: Attribute values for + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This represents the + * external ACS policies to select the channels w.r.t. the PCL weights. + * (QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL represents the channels and + * their PCL weights.) + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY: Mandatory to + * select a channel with non-zero PCL weight. + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED: Prefer a + * channel with non-zero PCL weight. + * + */ +enum qca_wlan_vendor_attr_external_acs_policy { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY, +}; + +/** + * qca_wlan_vendor_channel_prop_flags: This represent the flags for a channel. + * This is used by QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS. + */ +enum qca_wlan_vendor_channel_prop_flags { + /* Bits 0, 1, 2, and 3 are reserved */ + + /* Turbo channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_TURBO = 1 << 4, + /* CCK channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_CCK = 1 << 5, + /* OFDM channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_OFDM = 1 << 6, + /* 2.4 GHz spectrum channel. */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_2GHZ = 1 << 7, + /* 5 GHz spectrum channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_5GHZ = 1 << 8, + /* Only passive scan allowed */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_PASSIVE = 1 << 9, + /* Dynamic CCK-OFDM channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_DYN = 1 << 10, + /* GFSK channel (FHSS PHY) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_GFSK = 1 << 11, + /* Radar found on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_RADAR = 1 << 12, + /* 11a static turbo channel only */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_STURBO = 1 << 13, + /* Half rate channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HALF = 1 << 14, + /* Quarter rate channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_QUARTER = 1 << 15, + /* HT 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT20 = 1 << 16, + /* HT 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40PLUS = 1 << 17, + /* HT 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40MINUS = 1 << 18, + /* HT 40 intolerant */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40INTOL = 1 << 19, + /* VHT 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT20 = 1 << 20, + /* VHT 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT40PLUS = 1 << 21, + /* VHT 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT40MINUS = 1 << 22, + /* VHT 80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT80 = 1 << 23, + /* HT 40 intolerant mark bit for ACS use */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HT40INTOLMARK = 1 << 24, + /* Channel temporarily blocked due to noise */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_BLOCKED = 1 << 25, + /* VHT 160 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT160 = 1 << 26, + /* VHT 80+80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_VHT80_80 = 1 << 27, + /* HE 20 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE20 = 1 << 28, + /* HE 40 with extension channel above */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40PLUS = 1 << 29, + /* HE 40 with extension channel below */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40MINUS = 1 << 30, + /* HE 40 intolerant */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOL = 1 << 31, +}; + +/** + * qca_wlan_vendor_channel_prop_flags_2: This represents the flags for a + * channel, and is a continuation of qca_wlan_vendor_channel_prop_flags. This is + * used by QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2. + */ +enum qca_wlan_vendor_channel_prop_flags_2 { + /* HE 40 intolerant mark bit for ACS use */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE40INTOLMARK = 1 << 0, + /* HE 80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE80 = 1 << 1, + /* HE 160 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE160 = 1 << 2, + /* HE 80+80 channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HE80_80 = 1 << 3, +}; + +/** + * qca_wlan_vendor_channel_prop_flags_ext: This represent the extended flags for + * each channel. This is used by + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT. + */ +enum qca_wlan_vendor_channel_prop_flags_ext { + /* Radar found on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_RADAR_FOUND = 1 << 0, + /* DFS required on channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS = 1 << 1, + /* DFS required on channel for 2nd band of 80+80 */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS_CFREQ2 = 1 << 2, + /* If channel has been checked for DFS */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS_CLEAR = 1 << 3, + /* Excluded in 802.11d */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_11D_EXCLUDED = 1 << 4, + /* Channel Switch Announcement received on this channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_CSA_RECEIVED = 1 << 5, + /* Ad-hoc is not allowed */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DISALLOW_ADHOC = 1 << 6, + /* Station only channel */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DISALLOW_HOSTAP = 1 << 7, + /* DFS radar history for client device (STA mode) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_HISTORY_RADAR = 1 << 8, + /* DFS CAC valid for client device (STA mode) */ + QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_CAC_VALID = 1 << 9, +}; + +/** + * qca_wlan_vendor_external_acs_event_chan_info_attr: Represents per channel + * information. These attributes are sent as part of + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO. Each set of the following + * attributes correspond to a single channel. + */ +enum qca_wlan_vendor_external_acs_event_chan_info_attr { + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_INVALID = 0, + + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS = 1, + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags_ext. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT = 2, + /* frequency in MHz (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ = 3, + /* maximum regulatory transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER = 4, + /* maximum transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER = 5, + /* minimum transmission power (u32) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER = 6, + /* regulatory class id (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID = 7, + /* maximum antenna gain in (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN = 8, + /* VHT segment 0 (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 = 9, + /* VHT segment 1 (u8) */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 = 10, + /* A bitmask (u32) with flags specified in + * enum qca_wlan_vendor_channel_prop_flags_2. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS_2 = 11, + + /* + * VHT segment 0 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * should be used. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_0 = 12, + + /* + * VHT segment 1 in MHz (u32) and the attribute is mandatory. + * Note: Event QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS includes + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * along with + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1. + * + * If both the driver and user-space application supports the 6 GHz + * band, QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1 + * is deprecated and + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * should be considered. + * + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ_VHT_SEG_1 = 13, + + /* keep last */ + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST, + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX = + QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_pcl: Represents attributes for + * preferred channel list (PCL). These attributes are sent as part of + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL and + * QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST. + */ +enum qca_wlan_vendor_attr_pcl { + QCA_WLAN_VENDOR_ATTR_PCL_INVALID = 0, + + /* Channel number (u8) */ + QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL = 1, + /* Channel weightage (u8) */ + QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT = 2, + /* Channel frequency (u32) in MHz */ + QCA_WLAN_VENDOR_ATTR_PCL_FREQ = 3, + /* Channel flags (u32) + * bit 0 set: channel to be used for GO role, + * bit 1 set: channel to be used on CLI role, + * bit 2 set: channel must be considered for operating channel + * selection & peer chosen operating channel should be + * one of the channels with this flag set, + * bit 3 set: channel should be excluded in GO negotiation + */ + QCA_WLAN_VENDOR_ATTR_PCL_FLAG = 4, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PCL_LAST, + QCA_WLAN_VENDOR_ATTR_PCL_MAX = QCA_WLAN_VENDOR_ATTR_PCL_LAST - 1 +}; + +/** + * qca_wlan_vendor_attr_external_acs_event: Attribute to vendor sub-command + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This attribute will be sent by + * host driver. + */ +enum qca_wlan_vendor_attr_external_acs_event { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_INVALID = 0, + + /* This reason (u8) refers to enum qca_wlan_vendor_acs_select_reason. + * This helps ACS module to understand why ACS needs to be started. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON = 1, + /* Flag attribute to indicate if driver supports spectral scanning */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_SPECTRAL_SUPPORTED = 2, + /* Flag attribute to indicate if 11ac is offloaded to firmware */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_OFFLOAD_ENABLED = 3, + /* Flag attribute to indicate if driver provides additional channel + * capability as part of scan operation + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_ADD_CHAN_STATS_SUPPORT = 4, + /* Flag attribute to indicate interface status is UP */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AP_UP = 5, + /* Operating mode (u8) of interface. Takes one of enum nl80211_iftype + * values. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_SAP_MODE = 6, + /* Channel width (u8). It takes one of enum nl80211_chan_width values. + * This is the upper bound of channel width. ACS logic should try to get + * a channel with the specified width and if not found, look for lower + * values. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_WIDTH = 7, + /* This (u8) will hold values of one of enum nl80211_bands */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_BAND = 8, + /* PHY/HW mode (u8). Takes one of enum qca_wlan_vendor_acs_hw_mode + * values + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PHY_MODE = 9, + /* Array of (u32) supported frequency list among which ACS should choose + * best frequency. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_FREQ_LIST = 10, + /* Preferred channel list by the driver which will have array of nested + * values as per enum qca_wlan_vendor_attr_pcl attribute. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL = 11, + /* Array of nested attribute for each channel. It takes attr as defined + * in enum qca_wlan_vendor_external_acs_event_chan_info_attr. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO = 12, + /* External ACS policy such as PCL mandatory, PCL preferred, etc. + * It uses values defined in enum + * qca_wlan_vendor_attr_external_acs_policy. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY = 13, + /* Reference RF Operating Parameter (RROP) availability information + * (u16). It uses values defined in enum + * qca_wlan_vendor_attr_rropavail_info. + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_RROPAVAIL_INFO = 14, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_MAX = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_external_acs_channels: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS. This carries a list of channels + * in priority order as decided after ACS operation in userspace. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON: Required (u8). + * One of reason code from enum qca_wlan_vendor_acs_select_reason. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST: Required + * Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY: Required (u8). + * Primary channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY + * is still used if either of the driver or user space application doesn't + * support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY: Required (u8). + * Secondary channel number, required only for 160 and 80+80 MHz bandwidths. + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0: Required (u8). + * VHT seg0 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1: Required (u8). + * VHT seg1 channel number + * Note: If both the driver and user-space application supports the 6 GHz band, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 is deprecated and use + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1. + * To maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 + * is still used if either of the driver or user space application + * doesn't support the 6 GHz band. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH: Required (u8). + * Takes one of enum nl80211_chan_width values. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST: Required + * Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 in MHz (u32), + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY: Required (u32) + * Primary channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY: Required (u32) + * Secondary channel frequency in MHz used for HT 40 MHz channels. + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0: Required (u32) + * VHT seg0 channel frequency in MHz + * Note: If user-space application has no support of the 6GHz band, this + * attribute is optional. + * + * @QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1: Required (u32) + * VHT seg1 channel frequency in MHz + * Note: If user-space application has no support of the 6 GHz band, this + * attribute is optional. + */ +enum qca_wlan_vendor_attr_external_acs_channels { + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_INVALID = 0, + + /* One of reason code (u8) from enum qca_wlan_vendor_acs_select_reason + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON = 1, + + /* Array of nested values for each channel with following attributes: + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1, + * QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH + */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST = 2, + /* This (u8) will hold values of one of enum nl80211_bands */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND = 3, + /* Primary channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY = 4, + /* Secondary channel (u8) used for HT 40 MHz channels */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY = 5, + /* VHT seg0 channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0 = 6, + /* VHT seg1 channel (u8) */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1 = 7, + /* Channel width (u8). Takes one of enum nl80211_chan_width values. */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH = 8, + + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_LIST = 9, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_PRIMARY = 10, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_SECONDARY = 11, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG0 = 12, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_FREQUENCY_CENTER_SEG1 = 13, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST, + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX = + QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LAST - 1 +}; + +enum qca_chip_power_save_failure_reason { + /* Indicates if the reason for the failure is due to a protocol + * layer/module. + */ + QCA_CHIP_POWER_SAVE_FAILURE_REASON_PROTOCOL = 0, + /* Indicates if the reason for the failure is due to a hardware issue. + */ + QCA_CHIP_POWER_SAVE_FAILURE_REASON_HARDWARE = 1, +}; + +/** + * qca_attr_chip_power_save_failure: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE. This carries the requisite + * information leading to the power save failure. + */ +enum qca_attr_chip_power_save_failure { + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_INVALID = 0, + /* Reason to cause the power save failure. + * These reasons are represented by + * enum qca_chip_power_save_failure_reason. + */ + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON = 1, + + /* keep last */ + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST, + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_MAX = + QCA_ATTR_CHIP_POWER_SAVE_FAILURE_LAST - 1, +}; + +/** + * qca_wlan_vendor_nud_stats_data_pkt_flags: Flag representing the various + * data types for which the stats have to get collected. + */ +enum qca_wlan_vendor_nud_stats_data_pkt_flags { + QCA_WLAN_VENDOR_NUD_STATS_DATA_ARP = 1 << 0, + QCA_WLAN_VENDOR_NUD_STATS_DATA_DNS = 1 << 1, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_HANDSHAKE = 1 << 2, + QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV4 = 1 << 3, + QCA_WLAN_VENDOR_NUD_STATS_DATA_ICMPV6 = 1 << 4, + /* Used by QCA_ATTR_NUD_STATS_PKT_TYPE only in nud stats get + * to represent the stats of respective data type. + */ + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN = 1 << 5, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_SYN_ACK = 1 << 6, + QCA_WLAN_VENDOR_NUD_STATS_DATA_TCP_ACK = 1 << 7, +}; + +enum qca_wlan_vendor_nud_stats_set_data_pkt_info { + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_INVALID = 0, + /* Represents the data packet type to be monitored (u32). + * Host driver tracks the stats corresponding to each data frame + * represented by these flags. + * These data packets are represented by + * enum qca_wlan_vendor_nud_stats_data_pkt_flags + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_TYPE = 1, + /* Name corresponding to the DNS frame for which the respective DNS + * stats have to get monitored (string). Max string length 255. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DNS_DOMAIN_NAME = 2, + /* source port on which the respective proto stats have to get + * collected (u32). + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_SRC_PORT = 3, + /* destination port on which the respective proto stats have to get + * collected (u32). + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_PORT = 4, + /* IPv4 address for which the destined data packets have to be + * monitored. (in network byte order), u32. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV4 = 5, + /* IPv6 address for which the destined data packets have to be + * monitored. (in network byte order), 16 bytes array. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_DEST_IPV6 = 6, + + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST, + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_MAX = + QCA_ATTR_NUD_STATS_DATA_PKT_INFO_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_nud_stats_set: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET. This carries the requisite + * information to start/stop the NUD statistics collection. + */ +enum qca_attr_nud_stats_set { + QCA_ATTR_NUD_STATS_SET_INVALID = 0, + + /* Flag to start/stop the NUD statistics collection. + * Start - If included, Stop - If not included + */ + QCA_ATTR_NUD_STATS_SET_START = 1, + /* IPv4 address of the default gateway (in network byte order), u32 */ + QCA_ATTR_NUD_STATS_GW_IPV4 = 2, + /* Represents the list of data packet types to be monitored. + * Host driver tracks the stats corresponding to each data frame + * represented by these flags. + * These data packets are represented by + * enum qca_wlan_vendor_nud_stats_set_data_pkt_info + */ + QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO = 3, + + /* keep last */ + QCA_ATTR_NUD_STATS_SET_LAST, + QCA_ATTR_NUD_STATS_SET_MAX = + QCA_ATTR_NUD_STATS_SET_LAST - 1, +}; + +enum qca_attr_nud_data_stats { + QCA_ATTR_NUD_DATA_STATS_INVALID = 0, + /* Data packet type for which the stats are collected (u32). + * Represented by enum qca_wlan_vendor_nud_stats_data_pkt_flags + */ + QCA_ATTR_NUD_STATS_PKT_TYPE = 1, + /* Name corresponding to the DNS frame for which the respective DNS + * stats are monitored (string). Max string length 255. + */ + QCA_ATTR_NUD_STATS_PKT_DNS_DOMAIN_NAME = 2, + /* source port on which the respective proto stats are collected (u32). + */ + QCA_ATTR_NUD_STATS_PKT_SRC_PORT = 3, + /* destination port on which the respective proto stats are collected + * (u32). + */ + QCA_ATTR_NUD_STATS_PKT_DEST_PORT = 4, + /* IPv4 address for which the destined data packets have to be + * monitored. (in network byte order), u32. + */ + QCA_ATTR_NUD_STATS_PKT_DEST_IPV4 = 5, + /* IPv6 address for which the destined data packets have to be + * monitored. (in network byte order), 16 bytes array. + */ + QCA_ATTR_NUD_STATS_PKT_DEST_IPV6 = 6, + /* Data packet Request count received from netdev (u32). */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_FROM_NETDEV = 7, + /* Data packet Request count sent to lower MAC from upper MAC (u32). */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TO_LOWER_MAC = 8, + /* Data packet Request count received by lower MAC from upper MAC + * (u32) + */ + QCA_ATTR_NUD_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC = 9, + /* Data packet Request count successfully transmitted by the device + * (u32) + */ + QCA_ATTR_NUD_STATS_PKT_REQ_COUNT_TX_SUCCESS = 10, + /* Data packet Response count received by lower MAC (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC = 11, + /* Data packet Response count received by upper MAC (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC = 12, + /* Data packet Response count delivered to netdev (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_TO_NETDEV = 13, + /* Data Packet Response count that are dropped out of order (u32) */ + QCA_ATTR_NUD_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP = 14, + + /* keep last */ + QCA_ATTR_NUD_DATA_STATS_LAST, + QCA_ATTR_NUD_DATA_STATS_MAX = + QCA_ATTR_NUD_DATA_STATS_LAST - 1, +}; + +/** + * qca_attr_nud_stats_get: Attributes to vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET. This carries the requisite + * NUD statistics collected when queried. + */ +enum qca_attr_nud_stats_get { + QCA_ATTR_NUD_STATS_GET_INVALID = 0, + /* ARP Request count from netdev (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV = 1, + /* ARP Request count sent to lower MAC from upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC = 2, + /* ARP Request count received by lower MAC from upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC = 3, + /* ARP Request count successfully transmitted by the device (u32) */ + QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS = 4, + /* ARP Response count received by lower MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC = 5, + /* ARP Response count received by upper MAC (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC = 6, + /* ARP Response count delivered to netdev (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV = 7, + /* ARP Response count dropped due to out of order reception (u32) */ + QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP = 8, + /* Flag indicating if the station's link to the AP is active. + * Active Link - If included, Inactive link - If not included + */ + QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE = 9, + /* Flag indicating if there is any duplicate address detected (DAD). + * Yes - If detected, No - If not detected. + */ + QCA_ATTR_NUD_STATS_IS_DAD = 10, + /* List of Data packet types for which the stats are requested. + * This list does not carry ARP stats as they are done by the + * above attributes. Represented by enum qca_attr_nud_data_stats. + */ + QCA_ATTR_NUD_STATS_DATA_PKT_STATS = 11, + + /* keep last */ + QCA_ATTR_NUD_STATS_GET_LAST, + QCA_ATTR_NUD_STATS_GET_MAX = + QCA_ATTR_NUD_STATS_GET_LAST - 1, +}; + +enum qca_wlan_btm_candidate_status { + QCA_STATUS_ACCEPT = 0, + QCA_STATUS_REJECT_EXCESSIVE_FRAME_LOSS_EXPECTED = 1, + QCA_STATUS_REJECT_EXCESSIVE_DELAY_EXPECTED = 2, + QCA_STATUS_REJECT_INSUFFICIENT_QOS_CAPACITY = 3, + QCA_STATUS_REJECT_LOW_RSSI = 4, + QCA_STATUS_REJECT_HIGH_INTERFERENCE = 5, + QCA_STATUS_REJECT_UNKNOWN = 6, +}; + +enum qca_wlan_vendor_attr_btm_candidate_info { + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_INVALID = 0, + + /* 6-byte MAC address representing the BSSID of transition candidate */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID = 1, + /* Unsigned 32-bit value from enum qca_wlan_btm_candidate_status + * returned by the driver. It says whether the BSSID provided in + * QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_BSSID is acceptable by + * the driver, if not it specifies the reason for rejection. + * Note that the user-space can overwrite the transition reject reason + * codes provided by driver based on more information. + */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_STATUS = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_BTM_CANDIDATE_INFO_AFTER_LAST - 1, +}; + +enum qca_attr_trace_level { + QCA_ATTR_TRACE_LEVEL_INVALID = 0, + /* + * Nested array of the following attributes: + * QCA_ATTR_TRACE_LEVEL_MODULE, + * QCA_ATTR_TRACE_LEVEL_MASK. + */ + QCA_ATTR_TRACE_LEVEL_PARAM = 1, + /* + * Specific QCA host driver module. Please refer to the QCA host + * driver implementation to get the specific module ID. + */ + QCA_ATTR_TRACE_LEVEL_MODULE = 2, + /* Different trace level masks represented in the QCA host driver. */ + QCA_ATTR_TRACE_LEVEL_MASK = 3, + + /* keep last */ + QCA_ATTR_TRACE_LEVEL_AFTER_LAST, + QCA_ATTR_TRACE_LEVEL_MAX = + QCA_ATTR_TRACE_LEVEL_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_he_capabilities - IEEE 802.11ax HE capabilities + */ +enum qca_wlan_vendor_attr_get_he_capabilities { + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_INVALID = 0, + /* Whether HE capabilities is supported + * (u8 attribute: 0 = not supported, 1 = supported) + */ + QCA_WLAN_VENDOR_ATTR_HE_SUPPORTED = 1, + /* HE PHY capabilities, array of 3 u32 values */ + QCA_WLAN_VENDOR_ATTR_PHY_CAPAB = 2, + /* HE MAC capabilities (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_MAC_CAPAB = 3, + /* HE MCS map (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_HE_MCS = 4, + /* Number of SS (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_NUM_SS = 5, + /* RU count (u32 attribute) */ + QCA_WLAN_VENDOR_ATTR_RU_IDX_MASK = 6, + /* PPE threshold data, array of 8 u32 values */ + QCA_WLAN_VENDOR_ATTR_PPE_THRESHOLD = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_MAX = + QCA_WLAN_VENDOR_ATTR_HE_CAPABILITIES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_scan - Spectral scan config parameters + */ +enum qca_wlan_vendor_attr_spectral_scan { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INVALID = 0, + /* Number of times the chip enters spectral scan mode before + * deactivating spectral scans. When set to 0, chip will enter spectral + * scan mode continuously. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_COUNT = 1, + /* Spectral scan period. Period increment resolution is 256*Tclk, + * where Tclk = 1/44 MHz (Gmode), 1/40 MHz (Amode). u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SCAN_PERIOD = 2, + /* Spectral scan priority. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PRIORITY = 3, + /* Number of FFT data points to compute. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_SIZE = 4, + /* Enable targeted gain change before starting the spectral scan FFT. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_GC_ENA = 5, + /* Restart a queued spectral scan. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RESTART_ENA = 6, + /* Noise floor reference number for the calculation of bin power. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NOISE_FLOOR_REF = 7, + /* Disallow spectral scan triggers after TX/RX packets by setting + * this delay value to roughly SIFS time period or greater. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_INIT_DELAY = 8, + /* Number of strong bins (inclusive) per sub-channel, below + * which a signal is declared a narrow band tone. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_NB_TONE_THR = 9, + /* Specify the threshold over which a bin is declared strong (for + * scan bandwidth analysis). u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_STR_BIN_THR = 10, + /* Spectral scan report mode. u32 attribute. */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_WB_RPT_MODE = 11, + /* RSSI report mode, if the ADC RSSI is below + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR, + * then FFTs will not trigger, but timestamps and summaries get + * reported. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_RPT_MODE = 12, + /* ADC RSSI must be greater than or equal to this threshold (signed dB) + * to ensure spectral scan reporting with normal error code. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RSSI_THR = 13, + /* Format of frequency bin magnitude for spectral scan triggered FFTs: + * 0: linear magnitude, 1: log magnitude (20*log10(lin_mag)). + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_PWR_FORMAT = 14, + /* Format of FFT report to software for spectral scan triggered FFTs. + * 0: No FFT report (only spectral scan summary report) + * 1: 2-dword summary of metrics for each completed FFT + spectral scan + * report + * 2: 2-dword summary of metrics for each completed FFT + 1x-oversampled + * bins (in-band) per FFT + spectral scan summary report + * 3: 2-dword summary of metrics for each completed FFT + 2x-oversampled + * bins (all) per FFT + spectral scan summary report + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_RPT_MODE = 15, + /* Number of LSBs to shift out in order to scale the FFT bins. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BIN_SCALE = 16, + /* Set to 1 (with spectral_scan_pwr_format=1), to report bin magnitudes + * in dBm power. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DBM_ADJ = 17, + /* Per chain enable mask to select input ADC for search FFT. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_CHN_MASK = 18, + /* An unsigned 64-bit integer provided by host driver to identify the + * spectral scan request. This attribute is included in the scan + * response message for @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START + * and used as an attribute in + * @QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_STOP to identify the + * specific scan to be stopped. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_COOKIE = 19, + /* Skip interval for FFT reports. u32 attribute */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FFT_PERIOD = 20, + /* Set to report only one set of FFT results. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_SHORT_REPORT = 21, + /* Debug level for spectral module in driver. + * 0 : Verbosity level 0 + * 1 : Verbosity level 1 + * 2 : Verbosity level 2 + * 3 : Matched filterID display + * 4 : One time dump of FFT report + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DEBUG_LEVEL = 22, + /* Type of spectral scan request. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_attr_spectral_scan_request_type. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE = 23, + /* This specifies the frequency span over which spectral + * scan would be carried out. Its value depends on the + * value of QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE and + * the relation is as follows. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL + * Not applicable. Spectral scan would happen in the + * operating span. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE + * Center frequency (in MHz) of the span of interest or + * for convenience, center frequency (in MHz) of any channel + * in the span of interest. For 80+80 MHz agile spectral scan + * request it represents center frequency (in MHz) of the primary + * 80 MHz span or for convenience, center frequency (in MHz) of any + * channel in the primary 80 MHz span. If agile spectral scan is + * initiated without setting a valid frequency it returns the + * error code + * (QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED). + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY = 24, + /* Spectral scan mode. u32 attribute. + * It uses values defined in enum qca_wlan_vendor_spectral_scan_mode. + * If this attribute is not present, it is assumed to be + * normal mode (QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL). + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE = 25, + /* Spectral scan error code. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_error_code. + * This attribute is included only in failure scenarios. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE = 26, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA ring. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_RING_DEBUG = 27, + /* 8-bit unsigned value to enable/disable debug of the + * Spectral DMA buffers. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_DMA_BUFFER_DEBUG = 28, + /* This specifies the frequency span over which spectral scan would be + * carried out. Its value depends on the value of + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE and the relation is as + * follows. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL + * Not applicable. Spectral scan would happen in the operating span. + * QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE + * This attribute is applicable only for agile spectral scan + * requests in 80+80 MHz mode. It represents center frequency (in + * MHz) of the secondary 80 MHz span or for convenience, center + * frequency (in MHz) of any channel in the secondary 80 MHz span. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_FREQUENCY_2 = 29, + /* This attribute specifies the bandwidth to be used for spectral scan + * operation. This is an u8 attribute and uses the values in enum + * nl80211_chan_width. This is an optional attribute. + * If this attribute is not populated, the driver should configure the + * spectral scan bandwidth to the maximum value supported by the target + * for the current operating bandwidth. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_BANDWIDTH = 30, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_diag_stats - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_DIAG_STATS. + */ +enum qca_wlan_vendor_attr_spectral_diag_stats { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_INVALID = 0, + /* Number of spectral TLV signature mismatches. + * u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SIG_MISMATCH = 1, + /* Number of spectral phyerror events with insufficient length when + * parsing for secondary 80 search FFT report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_SEC80_SFFT_INSUFFLEN = 2, + /* Number of spectral phyerror events without secondary 80 + * search FFT report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_NOSEC80_SFFT = 3, + /* Number of spectral phyerror events with vht operation segment 1 id + * mismatches in search fft report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG1ID_MISMATCH = 4, + /* Number of spectral phyerror events with vht operation segment 2 id + * mismatches in search fft report. u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_VHTSEG2ID_MISMATCH = 5, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_DIAG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_cap - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. + */ +enum qca_wlan_vendor_attr_spectral_cap { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_INVALID = 0, + /* Flag attribute to indicate phydiag capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_PHYDIAG = 1, + /* Flag attribute to indicate radar detection capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RADAR = 2, + /* Flag attribute to indicate spectral capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_SPECTRAL = 3, + /* Flag attribute to indicate advanced spectral capability */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_ADVANCED_SPECTRAL = 4, + /* Spectral hardware generation. u32 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_cap_hw_gen. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN = 5, + /* Spectral bin scaling formula ID. u16 attribute. + * It uses values defined in enum + * qca_wlan_vendor_spectral_scan_cap_formula_id. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID = 6, + /* Spectral bin scaling param - low level offset. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET = 7, + /* Spectral bin scaling param - high level offset. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET = 8, + /* Spectral bin scaling param - RSSI threshold. + * s16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR = 9, + /* Spectral bin scaling param - default AGC max gain. + * u8 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN = 10, + /* Flag attribute to indicate agile spectral scan capability + * for 20/40/80 MHz modes. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL = 11, + /* Flag attribute to indicate agile spectral scan capability + * for 160 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_160 = 12, + /* Flag attribute to indicate agile spectral scan capability + * for 80+80 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_80_80 = 13, + /* Number of spectral detectors used for scan in 20 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_20_MHZ = 14, + /* Number of spectral detectors used for scan in 40 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_40_MHZ = 15, + /* Number of spectral detectors used for scan in 80 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80_MHZ = 16, + /* Number of spectral detectors used for scan in 160 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_160_MHZ = 17, + /* Number of spectral detectors used for scan in 80+80 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_80P80_MHZ = 18, + /* Flag attribute to indicate agile spectral scan capability + * for 320 MHz mode. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AGILE_SPECTRAL_320 = 19, + /* Number of spectral detectors used for scan in 320 MHz. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_NUM_DETECTORS_320_MHZ = 20, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_spectral_scan_status - used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS. + */ +enum qca_wlan_vendor_attr_spectral_scan_status { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_INVALID = 0, + /* Flag attribute to indicate whether spectral scan is enabled */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ENABLED = 1, + /* Flag attribute to indicate whether spectral scan is in progress*/ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_IS_ACTIVE = 2, + /* Spectral scan mode. u32 attribute. + * It uses values defined in enum qca_wlan_vendor_spectral_scan_mode. + * If this attribute is not present, normal mode + * (QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL is assumed to be + * requested. + */ + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE = 3, + + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_attr_spectral_scan_request_type: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START. This represents the + * spectral scan request types. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN_AND_CONFIG: Request to + * set the spectral parameters and start scan. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN: Request to + * only set the spectral parameters. + * @QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_CONFIG: Request to + * only start the spectral scan. + */ +enum qca_wlan_vendor_attr_spectral_scan_request_type { + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN_AND_CONFIG, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_SCAN, + QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_REQUEST_TYPE_CONFIG, +}; + +/** + * qca_wlan_vendor_spectral_scan_mode: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_MODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START and + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_STATUS_MODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_STATUS. This represents the + * spectral scan modes. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL: Normal spectral scan: + * spectral scan in the current operating span. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE: Agile spectral scan: + * spectral scan in the configured agile span. + */ +enum qca_wlan_vendor_spectral_scan_mode { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_NORMAL = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_MODE_AGILE = 1, +}; + +/** + * qca_wlan_vendor_spectral_scan_error_code: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_ERROR_CODE in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_START. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED: Changing the value + * of a parameter is not supported. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED: Requested spectral scan + * mode is not supported. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE: A parameter + * has invalid value. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED: A parameter + * is not initialized. + */ +enum qca_wlan_vendor_spectral_scan_error_code { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_UNSUPPORTED = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_MODE_UNSUPPORTED = 1, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE = 2, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_ERR_PARAM_NOT_INITIALIZED = 3, +}; + +/** + * qca_wlan_vendor_spectral_scan_cap_hw_gen: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. This represents the + * spectral hardware generation. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_1: generation 1 + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_2: generation 2 + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_3: generation 3 + */ +enum qca_wlan_vendor_spectral_scan_cap_hw_gen { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_1 = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_2 = 1, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_HW_GEN_3 = 2, +}; + +enum qca_wlan_vendor_tos { + QCA_WLAN_VENDOR_TOS_BK = 0, + QCA_WLAN_VENDOR_TOS_BE = 1, + QCA_WLAN_VENDOR_TOS_VI = 2, + QCA_WLAN_VENDOR_TOS_VO = 3, +}; + +/** + * enum qca_wlan_vendor_attr_active_tos - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ACTIVE_TOS. + */ +enum qca_wlan_vendor_attr_active_tos { + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_INVALID = 0, + /* Type Of Service - Represented by qca_wlan_vendor_tos */ + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS = 1, + /* Flag attribute representing the start (attribute included) or stop + * (attribute not included) of the respective TOS. + */ + QCA_WLAN_VENDOR_ATTR_ACTIVE_TOS_START = 2, +}; + +enum qca_wlan_vendor_hang_reason { + /* Unspecified reason */ + QCA_WLAN_HANG_REASON_UNSPECIFIED = 0, + /* No Map for the MAC entry for the received frame */ + QCA_WLAN_HANG_RX_HASH_NO_ENTRY_FOUND = 1, + /* Peer deletion timeout happened */ + QCA_WLAN_HANG_PEER_DELETION_TIMEDOUT = 2, + /* Peer unmap timeout */ + QCA_WLAN_HANG_PEER_UNMAP_TIMEDOUT = 3, + /* Scan request timed out */ + QCA_WLAN_HANG_SCAN_REQ_EXPIRED = 4, + /* Consecutive Scan attempt failures */ + QCA_WLAN_HANG_SCAN_ATTEMPT_FAILURES = 5, + /* Unable to get the message buffer */ + QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE = 6, + /* Current command processing is timedout */ + QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT = 7, + /* Timeout for an ACK from FW for suspend request */ + QCA_WLAN_HANG_SUSPEND_TIMEOUT = 8, + /* Timeout for an ACK from FW for resume request */ + QCA_WLAN_HANG_RESUME_TIMEOUT = 9, + /* Transmission timeout for consecutive data frames */ + QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT = 10, + /* Timeout for the TX completion status of data frame */ + QCA_WLAN_HANG_TX_COMPLETE_TIMEOUT = 11, + /* DXE failure for TX/RX, DXE resource unavailability */ + QCA_WLAN_HANG_DXE_FAILURE = 12, + /* WMI pending commands exceed the maximum count */ + QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS = 13, + /* Timeout for peer STA connection accept command's response from the + * FW in AP mode. This command is triggered when a STA (peer) connects + * to AP (DUT). + */ + QCA_WLAN_HANG_AP_STA_CONNECT_REQ_TIMEOUT = 14, + /* Timeout for the AP connection accept command's response from the FW + * in STA mode. This command is triggered when the STA (DUT) connects + * to an AP (peer). + */ + QCA_WLAN_HANG_STA_AP_CONNECT_REQ_TIMEOUT = 15, + /* Timeout waiting for the response to the MAC HW mode change command + * sent to FW as a part of MAC mode switch among DBS (Dual Band + * Simultaneous), SCC (Single Channel Concurrency), and MCC (Multi + * Channel Concurrency) mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CHANGE_TIMEOUT = 16, + /* Timeout waiting for the response from FW to configure the MAC HW's + * mode. This operation is to configure the single/two MACs in either + * SCC/MCC/DBS mode. + */ + QCA_WLAN_HANG_MAC_HW_MODE_CONFIG_TIMEOUT = 17, + /* Timeout waiting for response of VDEV start command from the FW */ + QCA_WLAN_HANG_VDEV_START_RESPONSE_TIMED_OUT = 18, + /* Timeout waiting for response of VDEV restart command from the FW */ + QCA_WLAN_HANG_VDEV_RESTART_RESPONSE_TIMED_OUT = 19, + /* Timeout waiting for response of VDEV stop command from the FW */ + QCA_WLAN_HANG_VDEV_STOP_RESPONSE_TIMED_OUT = 20, + /* Timeout waiting for response of VDEV delete command from the FW */ + QCA_WLAN_HANG_VDEV_DELETE_RESPONSE_TIMED_OUT = 21, + /* Timeout waiting for response of peer all delete request command to + * the FW on a specific VDEV. + */ + QCA_WLAN_HANG_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT = 22, + /* WMI sequence mismatch between WMI command and Tx completion */ + QCA_WLAN_HANG_WMI_BUF_SEQUENCE_MISMATCH = 23, + /* Write to Device HAL register failed */ + QCA_WLAN_HANG_REG_WRITE_FAILURE = 24, + /* No credit left to send the wow_wakeup_from_sleep to firmware */ + QCA_WLAN_HANG_SUSPEND_NO_CREDIT = 25, + /* Bus failure */ + QCA_WLAN_HANG_BUS_FAILURE = 26, + /* tasklet/credit latency found */ + QCA_WLAN_HANG_TASKLET_CREDIT_LATENCY_DETECT = 27, +}; + +/** + * enum qca_wlan_vendor_attr_hang - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_HANG. + */ +enum qca_wlan_vendor_attr_hang { + QCA_WLAN_VENDOR_ATTR_HANG_INVALID = 0, + /* Reason for the hang - u32 attribute with a value from enum + * qca_wlan_vendor_hang_reason. + */ + QCA_WLAN_VENDOR_ATTR_HANG_REASON = 1, + /* The binary blob data associated with the hang reason specified by + * QCA_WLAN_VENDOR_ATTR_HANG_REASON. This binary data is expected to + * contain the required dump to analyze the reason for the hang. + * NLA_BINARY attribute, the max size is 1024 bytes. + */ + QCA_WLAN_VENDOR_ATTR_HANG_REASON_DATA = 2, + + QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HANG_MAX = + QCA_WLAN_VENDOR_ATTR_HANG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_flush_pending_policy: Represents values for + * the policy to flush pending frames, configured via + * %QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING. This enumeration defines the + * valid values for %QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY. + * + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE: This value clears all + * the flush policy configured before. This command basically disables the + * flush config set by the user. + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE: This value configures + * the flush policy to be immediate. All pending packets for the peer/TID are + * flushed when this command/policy is received. + * @QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END: This value configures + * the flush policy to the end of TWT SP. All pending packets for the peer/TID + * are flushed when the end of TWT SP is reached. + */ +enum qca_wlan_vendor_flush_pending_policy { + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_NONE = 0, + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_IMMEDIATE = 1, + QCA_WLAN_VENDOR_FLUSH_PENDING_POLICY_TWT_SP_END = 2, +}; + +/** + * enum qca_wlan_vendor_attr_flush_pending - Attributes for + * flushing pending traffic in firmware. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_ADDR: Configure peer MAC address. + * @QCA_WLAN_VENDOR_ATTR_AC: Configure access category of the pending + * packets. It is u8 value with bit 0~3 represent AC_BE, AC_BK, + * AC_VI, AC_VO respectively. Set the corresponding bit to 1 to + * flush packets with access category. This is optional. See below. + * @QCA_WLAN_VENDOR_ATTR_TID_MASK: Configure TID mask of the pending packets. + * It is a u32 value with bit 0-7 representing TID 0-7. Set corresponding + * bit to 1 to act upon the TID. This is optional. Either this attribute or + * %QCA_WLAN_VENDOR_ATTR_AC must be provided. If both are provided, + * %QCA_WLAN_VENDOR_ATTR_TID_MASK takes precedence. If neither are provided + * it is an error. + * @QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY: Policy of flushing the pending + * packets corresponding to the peer/TID provided. It is a u32 value, + * represented by %enum qca_wlan_vendor_flush_pending_policy. This + * value is honored only when TID mask is provided. This is not honored when AC + * mask is provided. + */ +enum qca_wlan_vendor_attr_flush_pending { + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_PEER_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_AC = 2, + QCA_WLAN_VENDOR_ATTR_TID_MASK = 3, + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_POLICY = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_MAX = + QCA_WLAN_VENDOR_ATTR_FLUSH_PENDING_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_spectral_scan_cap_formula_id: Attribute values for + * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID in the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. This represents the + * Spectral bin scaling formula ID. + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING: No scaling + * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED: AGC gain + * and RSSI threshold based formula. + */ +enum qca_wlan_vendor_spectral_scan_cap_formula_id { + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING = 0, + QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_rropavail_info - Specifies whether Representative + * RF Operating Parameter (RROP) information is available, and if so, at which + * point in the application-driver interaction sequence it can be retrieved by + * the application from the driver. This point may vary by architecture and + * other factors. This is a u16 value. + */ +enum qca_wlan_vendor_attr_rropavail_info { + /* RROP information is unavailable. */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_UNAVAILABLE, + /* RROP information is available and the application can retrieve the + * information after receiving an QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS + * event from the driver. + */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_EXTERNAL_ACS_START, + /* RROP information is available only after a vendor specific scan + * (requested using QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN) has + * successfully completed. The application can retrieve the information + * after receiving the QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE event from + * the driver. + */ + QCA_WLAN_VENDOR_ATTR_RROPAVAIL_INFO_VSCAN_END, +}; + +/** + * enum qca_wlan_vendor_attr_rrop_info - Specifies vendor specific + * Representative RF Operating Parameter (RROP) information. It is sent for the + * vendor command QCA_NL80211_VENDOR_SUBCMD_GET_RROP_INFO. This information is + * intended for use by external Auto Channel Selection applications. It provides + * guidance values for some RF parameters that are used by the system during + * operation. These values could vary by channel, band, radio, and so on. + */ +enum qca_wlan_vendor_attr_rrop_info { + QCA_WLAN_VENDOR_ATTR_RROP_INFO_INVALID = 0, + + /* Representative Tx Power List (RTPL) which has an array of nested + * values as per attributes in enum qca_wlan_vendor_attr_rtplinst. + */ + QCA_WLAN_VENDOR_ATTR_RROP_INFO_RTPL = 1, + + QCA_WLAN_VENDOR_ATTR_RROP_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RROP_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_RROP_INFO_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_rtplinst - Specifies attributes for individual list + * entry instances in the Representative Tx Power List (RTPL). It provides + * simplified power values intended for helping external Auto channel Selection + * applications compare potential Tx power performance between channels, other + * operating conditions remaining identical. These values are not necessarily + * the actual Tx power values that will be used by the system. They are also not + * necessarily the max or average values that will be used. Instead, they are + * relative, summarized keys for algorithmic use computed by the driver or + * underlying firmware considering a number of vendor specific factors. + */ +enum qca_wlan_vendor_attr_rtplinst { + QCA_WLAN_VENDOR_ATTR_RTPLINST_INVALID = 0, + + /* Primary channel number (u8). + * Note: If both the driver and user space application support the + * 6 GHz band, this attribute is deprecated and + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY should be used. To + * maintain backward compatibility, + * QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY is still used if either the + * driver or user space application or both do not support the 6 GHz + * band. + */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY = 1, + /* Representative Tx power in dBm (s32) with emphasis on throughput. */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_THROUGHPUT = 2, + /* Representative Tx power in dBm (s32) with emphasis on range. */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_TXPOWER_RANGE = 3, + /* Primary channel center frequency (u32) in MHz */ + QCA_WLAN_VENDOR_ATTR_RTPLINST_PRIMARY_FREQUENCY = 4, + + QCA_WLAN_VENDOR_ATTR_RTPLINST_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RTPLINST_MAX = + QCA_WLAN_VENDOR_ATTR_RTPLINST_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_config_latency_level - Level for + * wlan latency module. + * + * There will be various of Wi-Fi functionality like scan/roaming/adaptive + * power saving which would causing data exchange out of service, this + * would be a big impact on latency. For latency sensitive applications over + * Wi-Fi are intolerant to such operations and thus would configure them + * to meet their respective needs. It is well understood by such applications + * that altering the default behavior would degrade the Wi-Fi functionality + * w.r.t the above pointed WLAN operations. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL: + * Default WLAN operation level which throughput orientated. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR: + * Use XR level to benefit XR (extended reality) application to achieve + * latency and power by via constraint scan/roaming/adaptive PS. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW: + * Use low latency level to benifit application like concurrent + * downloading or video streaming via constraint scan/adaptive PS. + * @QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW: + * Use ultra low latency level to benefit for gaming/voice + * application via constraint scan/roaming/adaptive PS. + */ +enum qca_wlan_vendor_attr_config_latency_level { + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR = 2, + /* legacy name */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_XR, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW = 3, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_wlan_mac - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO. + */ +enum qca_wlan_vendor_attr_mac { + QCA_WLAN_VENDOR_ATTR_MAC_INVALID = 0, + + /* MAC mode info list which has an array of nested values as + * per attributes in enum qca_wlan_vendor_attr_mac_mode_info. + */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mac_iface_info - Information of the connected + * Wi-Fi netdev interface on a respective MAC. + * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO. + */ +enum qca_wlan_vendor_attr_mac_iface_info { + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_INVALID = 0, + /* Wi-Fi netdev's interface index (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX = 1, + /* Associated frequency in MHz of the connected Wi-Fi interface (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mac_info - Points to MAC the information. + * Used by the attribute QCA_WLAN_VENDOR_ATTR_MAC_INFO of the + * vendor command QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO. + */ +enum qca_wlan_vendor_attr_mac_info { + QCA_WLAN_VENDOR_ATTR_MAC_INFO_INVALID = 0, + /* Hardware MAC ID associated for the MAC (u32) */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID = 1, + /* Band supported by the MAC at a given point. + * This is a u32 bitmask of BIT(NL80211_BAND_*) as described in %enum + * nl80211_band. + */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND = 2, + /* Refers to list of WLAN netdev interfaces associated with this MAC. + * Represented by enum qca_wlan_vendor_attr_mac_iface_info. + */ + QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MAC_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_logger_features - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET. + */ +enum qca_wlan_vendor_attr_get_logger_features { + QCA_WLAN_VENDOR_ATTR_LOGGER_INVALID = 0, + /* Unsigned 32-bit enum value of wifi_logger_supported_features */ + QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED = 1, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LOGGER_MAX = + QCA_WLAN_VENDOR_ATTR_LOGGER_AFTER_LAST - 1, +}; + +/** + * enum wifi_logger_supported_features - Values for supported logger features + */ +enum wifi_logger_supported_features { + WIFI_LOGGER_MEMORY_DUMP_FEATURE = (1 << (0)), + WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_FEATURE = (1 << (1)), + WIFI_LOGGER_CONNECT_EVENT_FEATURE = (1 << (2)), + WIFI_LOGGER_POWER_EVENT_FEATURE = (1 << (3)), + WIFI_LOGGER_WAKE_LOCK_FEATURE = (1 << (4)), + WIFI_LOGGER_VERBOSE_FEATURE = (1 << (5)), + WIFI_LOGGER_WATCHDOG_TIMER_FEATURE = (1 << (6)), + WIFI_LOGGER_DRIVER_DUMP_FEATURE = (1 << (7)), + WIFI_LOGGER_PACKET_FATE_FEATURE = (1 << (8)), +}; + +/** + * enum qca_wlan_tdls_caps_features_supported - Values for TDLS get + * capabilities features + */ +enum qca_wlan_tdls_caps_features_supported { + WIFI_TDLS_SUPPORT = (1 << (0)), + WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT = (1 << (1)), + WIFI_TDLS_OFFCHANNEL_SUPPORT = (1 << (2)) +}; + +/** + * enum qca_wlan_vendor_attr_tdls_get_capabilities - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES. + */ +enum qca_wlan_vendor_attr_tdls_get_capabilities { + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_INVALID = 0, + /* Indicates the max concurrent sessions */ + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS, + /* Indicates the support for features */ + /* Unsigned 32-bit bitmap qca_wlan_tdls_caps_features_supported + */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX = + QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_offloaded_packets_sending_control - Offload packets control + * command used as value for the attribute + * QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL. + */ +enum qca_wlan_offloaded_packets_sending_control { + QCA_WLAN_OFFLOADED_PACKETS_SENDING_CONTROL_INVALID = 0, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_START, + QCA_WLAN_OFFLOADED_PACKETS_SENDING_STOP +}; + +/** + * enum qca_wlan_vendor_attr_offloaded_packets - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS. + */ +enum qca_wlan_vendor_attr_offloaded_packets { + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_INVALID = 0, + /* Takes valid value from the enum + * qca_wlan_offloaded_packets_sending_control + * Unsigned 32-bit value + */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID, + /* array of u8 len: Max packet size */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA, + /* 6-byte MAC address used to represent source MAC address */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR, + /* 6-byte MAC address used to represent destination MAC address */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR, + /* Unsigned 32-bit value, in milli seconds */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD, + /* This optional unsigned 16-bit attribute is used for specifying + * ethernet protocol type. If not specified ethertype defaults to IPv4. + */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_ETHER_PROTO_TYPE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX = + QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_rssi_monitoring_control - RSSI control commands used as values + * by the attribute QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL. + */ +enum qca_wlan_rssi_monitoring_control { + QCA_WLAN_RSSI_MONITORING_CONTROL_INVALID = 0, + QCA_WLAN_RSSI_MONITORING_START, + QCA_WLAN_RSSI_MONITORING_STOP, +}; + +/** + * enum qca_wlan_vendor_attr_rssi_monitoring - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI. + */ +enum qca_wlan_vendor_attr_rssi_monitoring { + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_INVALID = 0, + /* Takes valid value from the enum + * qca_wlan_rssi_monitoring_control + * Unsigned 32-bit value enum qca_wlan_rssi_monitoring_control + */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL, + /* Unsigned 32-bit value */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID, + /* Signed 8-bit value in dBm */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI, + /* Signed 8-bit value in dBm */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI, + /* attributes to be used/received in callback */ + /* 6-byte MAC address used to represent current BSSID MAC address */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID, + /* Signed 8-bit value indicating the current RSSI */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX = + QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_ndp_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_NDP. + */ +enum qca_wlan_vendor_attr_ndp_params { + QCA_WLAN_VENDOR_ATTR_NDP_PARAM_INVALID = 0, + /* Unsigned 32-bit value + * enum of sub commands values in qca_wlan_ndp_sub_cmd + */ + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + /* Unsigned 16-bit value */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + /* NL attributes for data used NDP SUB cmds */ + /* Unsigned 32-bit value indicating a service info */ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + /* Unsigned 32-bit value; channel frequency in MHz */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, + /* Interface Discovery MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, + /* Interface name on which NDP is being created */ + QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + /* Unsigned 32-bit value for security */ + /* CONFIG_SECURITY is deprecated, use NCS_SK_TYPE/PMK/SCID instead */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, + /* Unsigned 32-bit value for QoS */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, + /* Array of u8: len = QCA_WLAN_VENDOR_ATTR_NAN_DP_APP_INFO_LEN */ + QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + /* Unsigned 32-bit value for NDP instance Id */ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + /* Array of instance Ids */ + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + /* Unsigned 32-bit value for initiator/responder NDP response code + * accept/reject + */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + /* NDI MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + /* Unsigned 32-bit value errors types returned by driver + * The wifi_nan.h in AOSP project platform/hardware/libhardware_legacy + * NanStatusType includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE, + /* Unsigned 32-bit value error values returned by driver + * The nan_i.h in AOSP project platform/hardware/qcom/wlan + * NanInternalStatusType includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + /* Unsigned 32-bit value for Channel setup configuration + * The wifi_nan.h in AOSP project platform/hardware/libhardware_legacy + * NanDataPathChannelCfg includes these values. + */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG, + /* Unsigned 32-bit value for Cipher Suite Shared Key Type */ + QCA_WLAN_VENDOR_ATTR_NDP_CSID, + /* Array of u8: len = NAN_PMK_INFO_LEN 32 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_PMK, + /* Security Context Identifier that contains the PMKID + * Array of u8: len = NAN_SCID_BUF_LEN 1024 bytes + */ + QCA_WLAN_VENDOR_ATTR_NDP_SCID, + /* Array of u8: len = NAN_SECURITY_MAX_PASSPHRASE_LEN 63 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE, + /* Array of u8: len = NAN_MAX_SERVICE_NAME_LEN 255 bytes */ + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME, + /* Unsigned 32-bit bitmap indicating schedule update + * BIT_0: NSS Update + * BIT_1: Channel list update + */ + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON, + /* Unsigned 32-bit value for NSS */ + QCA_WLAN_VENDOR_ATTR_NDP_NSS, + /* Unsigned 32-bit value for NUMBER NDP CHANNEL */ + QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS, + /* Unsigned 32-bit value for CHANNEL BANDWIDTH + * 0:20 MHz, 1:40 MHz, 2:80 MHz, 3:160 MHz + */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH, + /* Array of channel/band width */ + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO, + /* IPv6 address used by NDP (in network byte order), 16 bytes array. + * This attribute is used and optional for ndp request, ndp response, + * ndp indication, and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR = 27, + /* Unsigned 16-bit value indicating transport port used by NDP. + * This attribute is used and optional for ndp response, ndp indication, + * and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT = 28, + /* Unsigned 8-bit value indicating protocol used by NDP and assigned by + * the Internet Assigned Numbers Authority (IANA) as per: + * https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml + * This attribute is used and optional for ndp response, ndp indication, + * and ndp confirm. + */ + QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL = 29, + /* Unsigned 8-bit value indicating if NDP remote peer supports NAN NDPE. + * 1:support 0:not support + */ + QCA_WLAN_VENDOR_ATTR_PEER_NDPE_SUPPORT = 30, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_AFTER_LAST - 1, +}; + +enum qca_wlan_ndp_sub_cmd { + QCA_WLAN_VENDOR_ATTR_NDP_INVALID = 0, + /* Command to create a NAN data path interface */ + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE = 1, + /* Command to delete a NAN data path interface */ + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE = 2, + /* Command to initiate a NAN data path session */ + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST = 3, + /* Command to notify if the NAN data path session was sent */ + QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE = 4, + /* Command to respond to NAN data path session */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST = 5, + /* Command to notify on the responder about the response */ + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE = 6, + /* Command to initiate a NAN data path end */ + QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST = 7, + /* Command to notify the if end request was sent */ + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE = 8, + /* Command to notify the peer about the end request */ + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND = 9, + /* Command to confirm the NAN data path session is complete */ + QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND = 10, + /* Command to indicate the peer about the end request being received */ + QCA_WLAN_VENDOR_ATTR_NDP_END_IND = 11, + /* Command to indicate the peer of schedule update */ + QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND = 12 +}; + +/** + * enum qca_wlan_vendor_attr_nd_offload - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD. + */ +enum qca_wlan_vendor_attr_nd_offload { + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_INVALID = 0, + /* Flag to set Neighbour Discovery offload */ + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG, + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST - 1, +}; + +/** + * enum packet_filter_sub_cmd - Packet filter sub commands + */ +enum packet_filter_sub_cmd { + /** + * Write packet filter program and/or data. The driver/firmware should + * disable APF before writing into local buffer and re-enable APF after + * writing is done. + */ + QCA_WLAN_SET_PACKET_FILTER = 1, + /* Get packet filter feature capabilities from driver */ + QCA_WLAN_GET_PACKET_FILTER = 2, + /** + * Write packet filter program and/or data. User space will send the + * %QCA_WLAN_DISABLE_PACKET_FILTER command before issuing this command + * and will send the %QCA_WLAN_ENABLE_PACKET_FILTER afterwards. The key + * difference from that %QCA_WLAN_SET_PACKET_FILTER is the control over + * enable/disable is given to user space with this command. Also, + * user space sends the length of program portion in the buffer within + * %QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH. + */ + QCA_WLAN_WRITE_PACKET_FILTER = 3, + /* Read packet filter program and/or data */ + QCA_WLAN_READ_PACKET_FILTER = 4, + /* Enable APF feature */ + QCA_WLAN_ENABLE_PACKET_FILTER = 5, + /* Disable APF feature */ + QCA_WLAN_DISABLE_PACKET_FILTER = 6, +}; + +/** + * enum qca_wlan_vendor_attr_packet_filter - BPF control commands used by + * vendor QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER. + */ +enum qca_wlan_vendor_attr_packet_filter { + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_INVALID = 0, + /* Unsigned 32-bit enum passed using packet_filter_sub_cmd */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SUB_CMD, + /* Unsigned 32-bit value indicating the packet filter version */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_VERSION, + /* Unsigned 32-bit value indicating the packet filter id */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_ID, + /** + * Unsigned 32-bit value indicating the packet filter size including + * program + data. + */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_SIZE, + /* Unsigned 32-bit value indicating the packet filter current offset */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_CURRENT_OFFSET, + /* Program and/or data in bytes */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROGRAM, + /* Unsigned 32-bit value of the length of the program section in packet + * filter buffer. + */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_PROG_LENGTH = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_MAX = + QCA_WLAN_VENDOR_ATTR_PACKET_FILTER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_drv_info - WLAN driver info used by vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE. + */ +enum qca_wlan_vendor_drv_info { + QCA_WLAN_VENDOR_ATTR_DRV_INFO_INVALID = 0, + /* Maximum Message size info between firmware & HOST + * Unsigned 32-bit value + */ + QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DRV_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DRV_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_DRV_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_wake_stats - Wake lock stats used by vendor + * command QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS. + */ +enum qca_wlan_vendor_attr_wake_stats { + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_INVALID = 0, + /* Unsigned 32-bit value indicating the total count of wake event */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_CMD_EVENT_WAKE, + /* Array of individual wake count, each index representing wake reason + */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR, + /* Unsigned 32-bit value representing wake count array */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ, + /* Unsigned 32-bit total wake count value of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE, + /* Array of wake stats of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR, + /* Unsigned 32-bit total wake count value of driver/fw */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ, + /* Unsigned 32-bit total wake count value of packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_TOTAL_RX_DATA_WAKE, + /* Unsigned 32-bit wake count value unicast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_UNICAST_CNT, + /* Unsigned 32-bit wake count value multicast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value broadcast packets received */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RX_BROADCAST_CNT, + /* Unsigned 32-bit wake count value of ICMP packets */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP_PKT, + /* Unsigned 32-bit wake count value of ICMP6 packets */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_PKT, + /* Unsigned 32-bit value ICMP6 router advertisement */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RA, + /* Unsigned 32-bit value ICMP6 neighbor advertisement */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NA, + /* Unsigned 32-bit value ICMP6 neighbor solicitation */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_NS, + /* Unsigned 32-bit wake count value of receive side ICMP4 multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP4_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of receive side ICMP6 multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_ICMP6_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of receive side multicast */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_OTHER_RX_MULTICAST_CNT, + /* Unsigned 32-bit wake count value of a given RSSI breach */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_RSSI_BREACH_CNT, + /* Unsigned 32-bit wake count value of low RSSI */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_LOW_RSSI_CNT, + /* Unsigned 32-bit value GSCAN count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_GSCAN_CNT, + /* Unsigned 32-bit value PNO complete count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_PNO_COMPLETE_CNT, + /* Unsigned 32-bit value PNO match count */ + QCA_WLAN_VENDOR_ATTR_WAKE_STATS_PNO_MATCH_CNT, + /* keep last */ + QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_GET_WAKE_STATS_MAX = + QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_thermal_level - Defines various thermal levels + * configured by userspace to the driver/firmware. + * The values can be encapsulated in QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL or + * QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL attribute. + * The driver/firmware takes actions requested by userspace such as throttling + * wifi TX etc. in order to mitigate high temperature. + * + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE: Stop/clear all throttling actions. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT: Throttle TX lightly. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE: Throttle TX moderately. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE: Throttle TX severely. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL: Critical thermal level reached. + * @QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY: Emergency thermal level reached. + */ +enum qca_wlan_vendor_thermal_level { + QCA_WLAN_VENDOR_THERMAL_LEVEL_NONE = 0, + QCA_WLAN_VENDOR_THERMAL_LEVEL_LIGHT = 1, + QCA_WLAN_VENDOR_THERMAL_LEVEL_MODERATE = 2, + QCA_WLAN_VENDOR_THERMAL_LEVEL_SEVERE = 3, + QCA_WLAN_VENDOR_THERMAL_LEVEL_CRITICAL = 4, + QCA_WLAN_VENDOR_THERMAL_LEVEL_EMERGENCY = 5, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_cmd - Vendor subcmd attributes to set + * cmd value. Used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_cmd { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_INVALID = 0, + /* The value of command, driver will implement different operations + * according to this value. It uses values defined in + * enum qca_wlan_vendor_attr_thermal_cmd_type. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1, + /* Userspace uses this attribute to configure thermal level to the + * driver/firmware, or get thermal level from the driver/firmware. + * Used in request or response, u32 attribute, + * possible values are defined in enum qca_wlan_vendor_thermal_level. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_LEVEL = 2, + /* Userspace uses this attribute to configure the time in which the + * driver/firmware should complete applying settings it received from + * userspace with QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL + * command type. Used in request, u32 attribute, value is in + * milliseconds. A value of zero indicates to apply the settings + * immediately. The driver/firmware can delay applying the configured + * thermal settings within the time specified in this attribute if + * there is any critical ongoing operation. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3, + /* Nested attribute, the driver/firmware uses this attribute to report + * thermal statistics of different thermal levels to userspace when + * requested using the + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command + * type. This attribute contains a nested array of records of thermal + * statistics of multiple levels. The attributes used inside this nested + * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST - 1 +}; + +/** + * qca_wlan_vendor_attr_thermal_cmd_type: Attribute values for + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD. This represents the + * thermal command types sent to driver. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS: Request to + * get thermal shutdown configuration parameters for display. Parameters + * responded from driver are defined in + * enum qca_wlan_vendor_attr_get_thermal_params_rsp. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE: Request to + * get temperature. Host should respond with a temperature data. It is defined + * in enum qca_wlan_vendor_attr_thermal_get_temperature. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND: Request to execute thermal + * suspend action. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME: Request to execute thermal + * resume action. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to + * the driver/firmware. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current + * thermal level from the driver/firmware. The driver should respond with a + * thermal level defined in enum qca_wlan_vendor_thermal_level. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the + * current thermal statistics from the driver/firmware. The driver should + * respond with statistics of all thermal levels encapsulated in the attribute + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear + * the current thermal statistics for all thermal levels maintained in the + * driver/firmware and start counting from zero again. + */ +enum qca_wlan_vendor_attr_thermal_cmd_type { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_get_temperature - vendor subcmd attributes + * to get chip temperature by user. + * enum values are used for NL attributes for data used by + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE command for data used + * by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_get_temperature { + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_thermal_params_rsp - vendor subcmd attributes + * to get configuration parameters of thermal shutdown feature. Enum values are + * used by QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS command for data + * used by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_get_thermal_params_rsp { + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_INVALID = 0, + /* Indicate if the thermal shutdown feature is enabled. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_EN, + /* Indicate if the auto mode is enabled. + * Enable: Driver triggers the suspend/resume action. + * Disable: User space triggers the suspend/resume action. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_AUTO_EN, + /* Thermal resume threshold (degree Celsius). Issue the resume command + * if the temperature value is lower than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_RESUME_THRESH, + /* Thermal warning threshold (degree Celsius). FW reports temperature + * to driver if it's higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_WARNING_THRESH, + /* Thermal suspend threshold (degree Celsius). Issue the suspend command + * if the temperature value is higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SUSPEND_THRESH, + /* FW reports temperature data periodically at this interval (ms). + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SAMPLE_RATE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_MAX = + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_event - vendor subcmd attributes to + * report thermal events from driver to user space. + * enum values are used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT sub command. + */ +enum qca_wlan_vendor_attr_thermal_event { + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_TEMPERATURE, + /* Indication of resume completion from power save mode. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE, + /* Thermal level from the driver. + * u32 attribute. Possible values are defined in + * enum qca_wlan_vendor_thermal_level. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_LEVEL = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes + * to get thermal status from the driver/firmware. + * enum values are used for NL attributes encapsulated inside the + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute. + * + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each + * thermal level in milliseconds. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number + * of times the temperature crossed into the temperature range defined by the + * thermal level from both higher and lower directions. u32 size. + */ +enum qca_wlan_vendor_attr_thermal_stats { + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1, +}; + +/** + * enum he_fragmentation_val - HE fragmentation support values + * Indicates level of dynamic fragmentation that is supported by + * a STA as a recipient. + * HE fragmentation values are defined in IEEE P802.11ax/D2.0, 9.4.2.237.2 + * (HE MAC Capabilities Information field) and are used in HE Capabilities + * element to advertise the support. These values are validated in the driver + * to check the device capability and advertised in the HE Capabilities + * element. These values are used to configure testbed device to allow the + * advertised hardware capabilities to be downgraded for testing purposes. + * + * @HE_FRAG_DISABLE: no support for dynamic fragmentation + * @HE_FRAG_LEVEL1: support for dynamic fragments that are + * contained within an MPDU or S-MPDU, no support for dynamic fragments + * within an A-MPDU that is not an S-MPDU. + * @HE_FRAG_LEVEL2: support for dynamic fragments that are + * contained within an MPDU or S-MPDU and support for up to one dynamic + * fragment for each MSDU, each A-MSDU if supported by the recipient, and + * each MMPDU within an A-MPDU or multi-TID A-MPDU that is not an + * MPDU or S-MPDU. + * @HE_FRAG_LEVEL3: support for dynamic fragments that are + * contained within an MPDU or S-MPDU and support for multiple dynamic + * fragments for each MSDU and for each A-MSDU if supported by the + * recipient within an A-MPDU or multi-TID AMPDU and up to one dynamic + * fragment for each MMPDU in a multi-TID A-MPDU that is not an S-MPDU. + */ +enum he_fragmentation_val { + HE_FRAG_DISABLE, + HE_FRAG_LEVEL1, + HE_FRAG_LEVEL2, + HE_FRAG_LEVEL3, +}; + +/** + * enum he_mcs_config - HE MCS support configuration + * + * Configures the HE Tx/Rx MCS map in HE capability IE for given bandwidth. + * These values are used in driver to configure the HE MCS map to advertise + * Tx/Rx MCS map in HE capability and these values are applied for all the + * streams supported by the device. To configure MCS for different bandwidths, + * vendor command needs to be sent using this attribute with appropriate value. + * For example, to configure HE_80_MCS_0_7, send vendor command using HE MCS + * attribute with HE_80_MCS0_7. And to configure HE MCS for HE_160_MCS0_11 + * send this command using HE MCS config attribute with value HE_160_MCS0_11. + * These values are used to configure testbed device to allow the advertised + * hardware capabilities to be downgraded for testing purposes. The enum values + * are defined such that BIT[1:0] indicates the MCS map value. Values 3,7 and + * 11 are not used as BIT[1:0] value is 3 which is used to disable MCS map. + * These values are validated in the driver before setting the MCS map and + * driver returns error if the input is other than these enum values. + * + * @HE_80_MCS0_7: support for HE 80/40/20 MHz MCS 0 to 7 + * @HE_80_MCS0_9: support for HE 80/40/20 MHz MCS 0 to 9 + * @HE_80_MCS0_11: support for HE 80/40/20 MHz MCS 0 to 11 + * @HE_160_MCS0_7: support for HE 160 MHz MCS 0 to 7 + * @HE_160_MCS0_9: support for HE 160 MHz MCS 0 to 9 + * @HE_160_MCS0_11: support for HE 160 MHz MCS 0 to 11 + * @HE_80P80_MCS0_7: support for HE 80p80 MHz MCS 0 to 7 + * @HE_80P80_MCS0_9: support for HE 80p80 MHz MCS 0 to 9 + * @HE_80P80_MCS0_11: support for HE 80p80 MHz MCS 0 to 11 + */ +enum he_mcs_config { + HE_80_MCS0_7 = 0, + HE_80_MCS0_9 = 1, + HE_80_MCS0_11 = 2, + HE_160_MCS0_7 = 4, + HE_160_MCS0_9 = 5, + HE_160_MCS0_11 = 6, + HE_80P80_MCS0_7 = 8, + HE_80P80_MCS0_9 = 9, + HE_80P80_MCS0_11 = 10, +}; + +/** + * enum qca_wlan_ba_session_config - BA session configuration + * + * Indicates the configuration values for BA session configuration attribute. + * + * @QCA_WLAN_ADD_BA: Establish a new BA session with given configuration. + * @QCA_WLAN_DELETE_BA: Delete the existing BA session for given TID. + */ +enum qca_wlan_ba_session_config { + QCA_WLAN_ADD_BA = 1, + QCA_WLAN_DELETE_BA = 2, +}; + +/** + * enum qca_wlan_ac_type - Access category type + * + * Indicates the access category type value. + * + * @QCA_WLAN_AC_BE: BE access category + * @QCA_WLAN_AC_BK: BK access category + * @QCA_WLAN_AC_VI: VI access category + * @QCA_WLAN_AC_VO: VO access category + * @QCA_WLAN_AC_ALL: All ACs + */ +enum qca_wlan_ac_type { + QCA_WLAN_AC_BE = 0, + QCA_WLAN_AC_BK = 1, + QCA_WLAN_AC_VI = 2, + QCA_WLAN_AC_VO = 3, + QCA_WLAN_AC_ALL = 4, +}; + +/** + * enum qca_wlan_he_ltf_cfg - HE LTF configuration + * + * Indicates the HE LTF configuration value. + * + * @QCA_WLAN_HE_LTF_AUTO: HE-LTF is automatically set to the mandatory HE-LTF, + * based on the GI setting + * @QCA_WLAN_HE_LTF_1X: 1X HE LTF is 3.2us LTF + * @QCA_WLAN_HE_LTF_2X: 2X HE LTF is 6.4us LTF + * @QCA_WLAN_HE_LTF_4X: 4X HE LTF is 12.8us LTF + */ +enum qca_wlan_he_ltf_cfg { + QCA_WLAN_HE_LTF_AUTO = 0, + QCA_WLAN_HE_LTF_1X = 1, + QCA_WLAN_HE_LTF_2X = 2, + QCA_WLAN_HE_LTF_4X = 3, +}; + +/** + * enum qca_wlan_he_mac_padding_dur - HE trigger frame MAC padding duration + * + * Indicates the HE trigger frame MAC padding duration value. + * + * @QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME: no additional time required to + * process the trigger frame. + * @QCA_WLAN_HE_8US_OF_PROCESS_TIME: indicates the 8us of processing time for + * trigger frame. + * @QCA_WLAN_HE_16US_OF_PROCESS_TIME: indicates the 16us of processing time for + * trigger frame. + */ +enum qca_wlan_he_mac_padding_dur { + QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME = 0, + QCA_WLAN_HE_8US_OF_PROCESS_TIME = 1, + QCA_WLAN_HE_16US_OF_PROCESS_TIME = 2, +}; + +/** + * enum qca_wlan_he_om_ctrl_ch_bw - HE OM control field BW configuration + * + * Indicates the HE Operating mode control channel width setting value. + * + * @QCA_WLAN_HE_OM_CTRL_BW_20M: Primary 20 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_40M: Primary 40 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_80M: Primary 80 MHz + * @QCA_WLAN_HE_OM_CTRL_BW_160M: 160 MHz and 80+80 MHz + */ +enum qca_wlan_he_om_ctrl_ch_bw { + QCA_WLAN_HE_OM_CTRL_BW_20M = 0, + QCA_WLAN_HE_OM_CTRL_BW_40M = 1, + QCA_WLAN_HE_OM_CTRL_BW_80M = 2, + QCA_WLAN_HE_OM_CTRL_BW_160M = 3, +}; + +/** + * enum qca_wlan_keep_alive_data_type - Keep alive data type configuration + * + * Indicates the frame types to use for keep alive data. + * + * @QCA_WLAN_KEEP_ALIVE_DEFAULT: Driver default type used for keep alive. + * @QCA_WLAN_KEEP_ALIVE_DATA: Data frame type for keep alive. + * @QCA_WLAN_KEEP_ALIVE_MGMT: Management frame type for keep alive. + */ +enum qca_wlan_keep_alive_data_type { + QCA_WLAN_KEEP_ALIVE_DEFAULT = 0, + QCA_WLAN_KEEP_ALIVE_DATA = 1, + QCA_WLAN_KEEP_ALIVE_MGMT = 2, +}; + +/** + * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for + * HE operating mode control transmit request. These attributes are + * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and + * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS: Mandatory 8-bit unsigned value + * indicates the maximum number of spatial streams, NSS, that the STA + * supports in reception for PPDU bandwidths less than or equal to 80 MHz + * and is set to NSS - 1. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW: Mandatory 8-bit unsigned value + * indicates the operating channel width supported by the STA for both + * reception and transmission. Uses enum qca_wlan_he_om_ctrl_ch_bw values. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE: Mandatory 8-bit unsigned value + * indicates the all trigger based UL MU operations by the STA. + * 0 - UL MU operations are enabled by the STA. + * 1 - All triggered UL MU transmissions are suspended by the STA. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS: Mandatory 8-bit unsigned value + * indicates the maximum number of space-time streams, NSTS, that + * the STA supports in transmission and is set to NSTS - 1. + * + * @QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE: 8-bit unsigned value + * combined with the UL MU Disable subfield and the recipient's setting + * of the OM Control UL MU Data Disable RX Support subfield in the HE MAC + * capabilities to determine which HE TB PPDUs are possible by the + * STA to transmit. + * 0 - UL MU data operations are enabled by the STA. + * 1 - Determine which HE TB PPDU types are allowed by the STA if UL MU disable + * bit is not set, else UL MU Tx is suspended. + * + */ +enum qca_wlan_vendor_attr_he_omi_tx { + QCA_WLAN_VENDOR_ATTR_HE_OMI_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS = 1, + QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW = 2, + QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE = 3, + QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS = 4, + QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX = + QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST - 1, +}; + + /** + * enum qca_wlan_vendor_phy_mode - Different PHY modes + * These values are used with %QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE. + * + * @QCA_WLAN_VENDOR_PHY_MODE_AUTO: autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO: 2.4 GHz 802.11b/g/n/ax autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO: 5 GHz 802.11a/n/ac/ax autoselect + * @QCA_WLAN_VENDOR_PHY_MODE_11A: 5 GHz, OFDM + * @QCA_WLAN_VENDOR_PHY_MODE_11B: 2.4 GHz, CCK + * @QCA_WLAN_VENDOR_PHY_MODE_11G: 2.4 GHz, OFDM + * @QCA_WLAN_VENDOR_PHY_MODE_11AGN: Support 802.11n in both 2.4 GHz and 5 GHz + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20: 2.4 GHz, HT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS: 2.4 GHz, HT40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS: 2.4 GHz, HT40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40: 2.4 GHz, Auto HT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20: 5 GHz, HT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS: 5 GHz, HT40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS: 5 GHz, HT40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40: 5 GHz, Auto HT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20: 5 GHz, VHT20 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS: 5 GHz, VHT40 (Ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS: 5 GHz VHT40 (Ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40: 5 GHz, VHT40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80: 5 GHz, VHT80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80: 5 GHz, VHT80+80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160: 5 GHz, VHT160 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20: HE20 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40: HE40 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS: HE40 (ext ch +1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS: HE40 (ext ch -1) + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80: HE80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80: HE 80P80 + * @QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160: HE160 + */ +enum qca_wlan_vendor_phy_mode { + QCA_WLAN_VENDOR_PHY_MODE_AUTO = 0, + QCA_WLAN_VENDOR_PHY_MODE_2G_AUTO = 1, + QCA_WLAN_VENDOR_PHY_MODE_5G_AUTO = 2, + QCA_WLAN_VENDOR_PHY_MODE_11A = 3, + QCA_WLAN_VENDOR_PHY_MODE_11B = 4, + QCA_WLAN_VENDOR_PHY_MODE_11G = 5, + QCA_WLAN_VENDOR_PHY_MODE_11AGN = 6, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20 = 7, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS = 8, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS = 9, + QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40 = 10, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20 = 11, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS = 12, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS = 13, + QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40 = 14, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20 = 15, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS = 16, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS = 17, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40 = 18, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80 = 19, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80 = 20, + QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160 = 21, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20 = 22, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40 = 23, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS = 24, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS = 25, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80 = 26, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80 = 27, + QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160 = 28, +}; + +/* Attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION + */ +enum qca_wlan_vendor_attr_wifi_test_config { + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_INVALID = 0, + /* 8-bit unsigned value to configure the driver to enable/disable + * WMM feature. This attribute is used to configure testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE = 1, + + /* 8-bit unsigned value to configure the driver to accept/reject + * the addba request from peer. This attribute is used to configure + * the testbed device. + * 1-accept addba, 0-reject addba + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ = 2, + + /* 8-bit unsigned value to configure the driver to send or not to + * send the addba request to peer. + * This attribute is used to configure the testbed device. + * 1-send addba, 0-do not send addba + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ = 3, + + /* 8-bit unsigned value to indicate the HE fragmentation support. + * Uses enum he_fragmentation_val values. + * This attribute is used to configure the testbed device to + * allow the advertised hardware capabilities to be downgraded + * for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION = 4, + + /* 8-bit unsigned value to indicate the HE MCS support. + * Uses enum he_mcs_config values. + * This attribute is used to configure the testbed device to + * allow the advertised hardware capabilities to be downgraded + * for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS = 5, + + /* 8-bit unsigned value to configure the driver to allow or not to + * allow the connection with WEP/TKIP in HT/VHT/HE modes. + * This attribute is used to configure the testbed device. + * 1-allow WEP/TKIP in HT/VHT/HE, 0-do not allow WEP/TKIP. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE = 6, + + /* 8-bit unsigned value to configure the driver to add a + * new BA session or delete the existing BA session for + * given TID. ADDBA command uses the buffer size and TID + * configuration if user specifies the values else default + * value for buffer size is used for all TIDs if the TID + * also not specified. For DEL_BA command TID value is + * required to process the command. + * Uses enum qca_wlan_ba_session_config values. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION = 7, + + /* 16-bit unsigned value to configure the buffer size in addba + * request and response frames. + * This attribute is used to configure the testbed device. + * The range of the value is 0 to 256. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE = 8, + + /* 8-bit unsigned value to configure the buffer size in addba + * request and response frames. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID = 9, + + /* 8-bit unsigned value to configure the no ack policy. + * To configure no ack policy, access category value is + * required to process the command. + * This attribute is used to configure the testbed device. + * 1 - enable no ack, 0 - disable no ack. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK = 10, + + /* 8-bit unsigned value to configure the AC for no ack policy + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_ac_type values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC = 11, + + /* 8-bit unsigned value to configure the HE LTF + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_he_ltf_cfg values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF = 12, + + /* 8-bit unsigned value to configure the tx beamformee. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE = 13, + + /* 8-bit unsigned value to configure the tx beamformee number + * of space-time streams. + * This attribute is used to configure the testbed device. + * The range of the value is 0 to 8. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS = 14, + + /* 8-bit unsigned value to configure the MU EDCA params for given AC + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_ac_type values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AC = 15, + + /* 8-bit unsigned value to configure the MU EDCA AIFSN for given AC + * To configure MU EDCA AIFSN value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AIFSN = 16, + + /* 8-bit unsigned value to configure the MU EDCA ECW min value for + * given AC. + * To configure MU EDCA ECW min value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_ECWMIN = 17, + + /* 8-bit unsigned value to configure the MU EDCA ECW max value for + * given AC. + * To configure MU EDCA ECW max value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_ECWMAX = 18, + + /* 8-bit unsigned value to configure the MU EDCA timer for given AC + * To configure MU EDCA timer value, MU EDCA access category value + * is required to process the command. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_TIMER = 19, + + /* 8-bit unsigned value to configure the HE trigger frame MAC padding + * duration. + * This attribute is used to configure the testbed device. + * Uses the enum qca_wlan_he_mac_padding_dur values. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR = 20, + + /* 8-bit unsigned value to override the MU EDCA params to defaults + * regardless of the AP beacon MU EDCA params. If it is enabled use + * the default values else use the MU EDCA params from AP beacon. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA = 21, + + /* 8-bit unsigned value to configure the support for receiving + * an MPDU that contains an operating mode control subfield. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP = 22, + + /* Nested attribute values required to setup the TWT session. + * enum qca_wlan_vendor_attr_twt_setup provides the necessary + * information to set up the session. It contains broadcast flags, + * set_up flags, trigger value, flow type, flow ID, wake interval + * exponent, protection, target wake time, wake duration, wake interval + * mantissa. These nested attributes are used to setup a host triggered + * TWT session. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP = 23, + + /* This nested attribute is used to terminate the current TWT session. + * It does not currently carry any attributes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE = 24, + + /* This nested attribute is used to suspend the current TWT session. + * It does not currently carry any attributes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SUSPEND = 25, + + /* Nested attribute values to indicate the request for resume. + * This attribute is used to resume the TWT session. + * enum qca_wlan_vendor_attr_twt_resume provides the necessary + * parameters required to resume the TWT session. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME = 26, + + /* 8-bit unsigned value to set the HE operating mode control + * (OM CTRL) Channel Width subfield. + * The Channel Width subfield indicates the operating channel width + * supported by the STA for both reception and transmission. + * Uses the enum qca_wlan_he_om_ctrl_ch_bw values. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW = 27, + + /* 8-bit unsigned value to configure the number of spatial + * streams in HE operating mode control field. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS = 28, + + /* Flag attribute to configure the UL MU disable bit in + * HE operating mode control field. + * This setting is cleared with the + * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG + * flag attribute to reset defaults. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_UL_MU_DISABLE = 29, + + /* Flag attribute to clear the previously set HE operating mode + * control field configuration. + * This attribute is used to configure the testbed device to reset + * defaults to clear any previously set HE operating mode control + * field configuration. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG = 30, + + /* 8-bit unsigned value to configure HE single user PPDU + * transmission. By default this setting is disabled and it + * is disabled in the reset defaults of the device configuration. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU = 31, + + /* 8-bit unsigned value to configure action frame transmission + * in HE trigger based PPDU transmission. + * By default this setting is disabled and it is disabled in + * the reset defaults of the device configuration. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU = 32, + + /* Nested attribute to indicate HE operating mode control field + * transmission. It contains operating mode control field Nss, + * channel bandwidth, Tx Nsts and UL MU disable attributes. + * These nested attributes are used to send HE operating mode control + * with configured values. + * Uses the enum qca_wlan_vendor_attr_he_omi_tx attributes. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX = 33, + + /* 8-bit unsigned value to configure +HTC_HE support to indicate the + * support for the reception of a frame that carries an HE variant + * HT Control field. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP = 34, + + /* 8-bit unsigned value to configure VHT support in 2.4G band. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT = 35, + + /* 8-bit unsigned value to configure HE testbed defaults. + * This attribute is used to configure the testbed device. + * 1-set the device HE capabilities to testbed defaults. + * 0-reset the device HE capabilities to supported config. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS = 36, + + /* 8-bit unsigned value to configure TWT request support. + * This attribute is used to configure the testbed device. + * 1-enable, 0-disable. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT = 37, + + /* 8-bit unsigned value to configure protection for Management + * frames when PMF is enabled for the association. + * This attribute is used to configure the testbed device. + * 0-use the correct key, 1-use an incorrect key, 2-disable protection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION = 38, + + /* Flag attribute to inject Disassociation frame to the connected AP. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX = 39, + + /* 8-bit unsigned value to configure an override for the RSNXE Used + * subfield in the MIC control field of the FTE in FT Reassociation + * Request frame. + * 0 - Default behavior, 1 - override with 1, 2 - override with 0. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED = 40, + + /* 8-bit unsigned value to configure the driver to ignore CSA (Channel + * Switch Announcement) when STA is in connected state. + * 0 - Default behavior, 1 - Ignore CSA. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA = 41, + + /* Nested attribute values required to configure OCI (Operating Channel + * Information). Attributes defined in enum + * qca_wlan_vendor_attr_oci_override are nested within this attribute. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE = 42, + + /* 8-bit unsigned value to configure the driver/firmware to ignore SA + * Query timeout. If this configuration is enabled STA shall not send + * Deauthentication frmae when SA Query times out (mainly, after a + * channel switch when OCV is enabled). + * 0 - Default behavior, 1 - Ignore SA Query timeout. + * This attribute is used to configure the testbed device. + * This attribute can be configured only when STA is in associated state + * and the configuration is valid until the disconnection. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT = 43, + + /* 8-bit unsigned value to configure the driver/firmware to start or + * stop transmitting FILS discovery frames. + * 0 - Stop transmitting FILS discovery frames + * 1 - Start transmitting FILS discovery frames + * This attribute is used to configure the testbed device. + * This attribute can be configured only in AP mode and the + * configuration is valid until AP restart. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FILS_DISCOVERY_FRAMES_TX = 44, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable full bandwidth UL MU-MIMO subfield in the HE PHY capabilities + * information field. + * 0 - Disable full bandwidth UL MU-MIMO subfield + * 1 - Enable full bandwidth UL MU-MIMO subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO = 45, + + /* 16-bit unsigned value to configure the driver with a specific BSS + * max idle period to advertise in the BSS Max Idle Period element + * (IEEE Std 802.11-2016, 9.4.2.79) in (Re)Association Request frames. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD = 46, + + /* 8-bit unsigned value to configure the driver to use only RU 242 tone + * for data transmission. + * 0 - Default behavior, 1 - Configure RU 242 tone for data Tx. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX = 47, + + /* 8-bit unsigned value to configure the driver to disable data and + * management response frame transmission to test the BSS max idle + * feature. + * 0 - Default behavior, 1 - Disable data and management response Tx. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX = 48, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Punctured Preamble Rx subfield in the HE PHY capabilities + * information field. + * 0 - Disable Punctured Preamble Rx subfield + * 1 - Enable Punctured Preamble Rx subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX = 49, + + /* 8-bit unsigned value to configure the driver to ignore the SAE H2E + * requirement mismatch for 6 GHz connection. + * 0 - Default behavior, 1 - Ignore SAE H2E requirement mismatch. + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE = 50, + + /* 8-bit unsigned value to configure the driver to allow 6 GHz + * connection with all security modes. + * 0 - Default behavior, 1 - Allow 6 GHz connection with all security + * modes. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_6GHZ_SECURITY_TEST_MODE = 51, + + /* 8-bit unsigned value to configure the driver to transmit data with + * ER SU PPDU type. + * + * 0 - Default behavior, 1 - Enable ER SU PPDU type TX. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE = 52, + + /* 8-bit unsigned value to configure the driver to use Data or + * Management frame type for keep alive data. + * Uses enum qca_wlan_keep_alive_data_type values. + * + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53, + + /* 8-bit unsigned value to configure the driver to use scan request + * BSSID value in Probe Request frame RA(A1) during the scan. The + * driver saves this configuration and applies this setting to all user + * space scan requests until the setting is cleared. If this + * configuration is set, the driver uses the BSSID value from the scan + * request to set the RA(A1) in the Probe Request frames during the + * scan. + * + * 0 - Default behavior uses the broadcast RA in Probe Request frames. + * 1 - Uses the scan request BSSID in RA in Probe Request frames. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54, + + /* 8-bit unsigned value to configure the driver to enable/disable the + * BSS max idle period support. + * + * 0 - Disable the BSS max idle support. + * 1 - Enable the BSS max idle support. + * This attribute is used for testing purposes. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Rx control frame to MultiBSS subfield in the HE MAC + * capabilities information field. + * 0 - Disable Rx control frame to MultiBSS subfield + * 1 - Enable Rx control frame to MultiBSS subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS = 56, + + /* 8-bit unsigned value to configure the driver/firmware to enable or + * disable Broadcast TWT support subfield in the HE MAC capabilities + * information field. + * 0 - Disable Broadcast TWT support subfield + * 1 - Enable Broadcast TWT support subfield + * This attribute is used to configure the testbed device. + */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT = 57, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX = + QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_twt_operation - Operation of the config TWT request + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION. + * The response for the respective operations can be either synchronous or + * asynchronous (wherever specified). If synchronous, the response to this + * operation is obtained in the corresponding vendor command reply to the user + * space. For the asynchronous case the response is obtained as an event with + * the same operation type. + * + * Drivers shall support either of these modes but not both simultaneously. + * This support for asynchronous mode is advertised through the flag + * QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT. If this flag is not advertised, + * the driver shall support synchronous mode. + * + * @QCA_WLAN_TWT_SET: Setup a TWT session. Required parameters are configured + * through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Depending upon the + * @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, this is either a + * synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_GET: Get the configured TWT parameters. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. This is a synchronous operation. + * + * @QCA_WLAN_TWT_TERMINATE: Terminate the TWT session. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup. + * This terminate can either get triggered by the user space or can as well be + * a notification from the firmware if it initiates a terminate. + * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, + * the request from user space can either be a synchronous or asynchronous + * operation. + * + * @QCA_WLAN_TWT_SUSPEND: Suspend the TWT session. Required parameters are + * obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_setup. Valid only after the TWT session is setup. + * Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT capability, + * this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_RESUME: Resume the TWT session. Required parameters are + * configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the enum + * qca_wlan_vendor_attr_twt_resume. Valid only after the TWT session is setup. + * This can as well be a notification from the firmware on a QCA_WLAN_TWT_NUDGE + * request. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT + * capability, this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_NUDGE: Suspend and resume the TWT session. TWT nudge is a + * combination of suspend and resume in a single request. Required parameters + * are configured through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refers the + * enum qca_wlan_vendor_attr_twt_nudge. Valid only after the TWT session is + * setup. Depending upon the @QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT + * capability, this is either a synchronous or asynchronous operation. + * + * @QCA_WLAN_TWT_GET_STATS: Get the TWT session traffic statistics information. + * Refers the enum qca_wlan_vendor_attr_twt_stats. Valid only after the TWT + * session is setup. It's a synchronous operation. + * + * @QCA_WLAN_TWT_CLEAR_STATS: Clear TWT session traffic statistics information. + * Valid only after the TWT session is setup. It's a synchronous operation. + * + * @QCA_WLAN_TWT_GET_CAPABILITIES: Get TWT capabilities of this device and its + * peer. Refers the enum qca_wlan_vendor_attr_twt_capability. It's a synchronous + * operation. + * + * @QCA_WLAN_TWT_SETUP_READY_NOTIFY: Notify userspace that the firmare is + * ready for a new TWT session setup after it issued a TWT teardown. + * + * @QCA_WLAN_TWT_SET_PARAM: Configure TWT related parameters. Required + * parameters are obtained through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. Refer + * the enum qca_wlan_vendor_attr_twt_set_param. + */ +enum qca_wlan_twt_operation { + QCA_WLAN_TWT_SET = 0, + QCA_WLAN_TWT_GET = 1, + QCA_WLAN_TWT_TERMINATE = 2, + QCA_WLAN_TWT_SUSPEND = 3, + QCA_WLAN_TWT_RESUME = 4, + QCA_WLAN_TWT_NUDGE = 5, + QCA_WLAN_TWT_GET_STATS = 6, + QCA_WLAN_TWT_CLEAR_STATS = 7, + QCA_WLAN_TWT_GET_CAPABILITIES = 8, + QCA_WLAN_TWT_SETUP_READY_NOTIFY = 9, + QCA_WLAN_TWT_SET_PARAM = 10, +}; + +/** + * enum qca_wlan_vendor_attr_config_twt: Defines attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION: u8 attribute. Specify the TWT + * operation of this request. Possible values are defined in enum + * qca_wlan_twt_operation. The parameters for the respective operation is + * specified through QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS: Nested attribute representing the + * parameters configured for TWT. These parameters are represented by + * enum qca_wlan_vendor_attr_twt_setup, enum qca_wlan_vendor_attr_twt_resume, + * enum qca_wlan_vendor_attr_twt_set_param, or + * enum qca_wlan_vendor_attr_twt_stats based on the operation. + */ +enum qca_wlan_vendor_attr_config_twt { + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_bss_filter - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * The user can add/delete the filter by specifying the BSSID/STA MAC address in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR, filter type in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE, add/delete action in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION in the request. The user can get the + * statistics of an unassociated station by specifying the MAC address in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR, station type in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE, GET action in + * QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION in the request. The user also can get + * the statistics of all unassociated stations by specifying the Broadcast MAC + * address (ff:ff:ff:ff:ff:ff) in QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR with + * above procedure. In the response, driver shall specify statistics + * information nested in QCA_WLAN_VENDOR_ATTR_BSS_FILTER_STA_STATS. + */ +enum qca_wlan_vendor_attr_bss_filter { + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAC_ADDR = 1, + /* Other BSS filter type, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_bss_filter_type. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_TYPE = 2, + /* Other BSS filter action, unsigned 8 bit value. One of the values + * in enum qca_wlan_vendor_bss_filter_action. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_ACTION = 3, + /* Array of nested attributes where each entry is the statistics + * information of the specified station that belong to another BSS. + * Attributes for each entry are taken from enum + * qca_wlan_vendor_bss_filter_sta_stats. + * Other BSS station configured in + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER with filter type + * QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA. + * Statistics returned by QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER + * with filter action QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET. + */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_STA_STATS = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_MAX = + QCA_WLAN_VENDOR_ATTR_BSS_FILTER_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_bss_filter_type - Type of + * filter used in other BSS filter operations. Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_TYPE_BSSID: BSSID filter + * @QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA: Station MAC address filter + */ +enum qca_wlan_vendor_bss_filter_type { + QCA_WLAN_VENDOR_BSS_FILTER_TYPE_BSSID, + QCA_WLAN_VENDOR_BSS_FILTER_TYPE_STA, +}; + +/** + * enum qca_wlan_vendor_bss_filter_action - Type of + * action in other BSS filter operations. Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_ADD: Add filter + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_DEL: Delete filter + * @QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET: Get the statistics + */ +enum qca_wlan_vendor_bss_filter_action { + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_ADD, + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_DEL, + QCA_WLAN_VENDOR_BSS_FILTER_ACTION_GET, +}; + +/** + * enum qca_wlan_vendor_bss_filter_sta_stats - Attributes for + * the statistics of a specific unassociated station belonging to another BSS. + * The statistics provides information of the unassociated station + * filtered by other BSS operation - such as MAC, signal value. + * Used by the vendor command QCA_NL80211_VENDOR_SUBCMD_BSS_FILTER. + * + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAC: MAC address of the station. + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI: Last received signal strength + * of the station. Unsigned 8 bit number containing RSSI. + * @QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI_TS: Time stamp of the host + * driver for the last received RSSI. Unsigned 64 bit number containing + * nanoseconds from the boottime. + */ +enum qca_wlan_vendor_bss_filter_sta_stats { + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_INVALID = 0, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAC = 1, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI = 2, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_RSSI_TS = 3, + + /* keep last */ + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_MAX = + QCA_WLAN_VENDOR_BSS_FILTER_STA_STATS_AFTER_LAST - 1 +}; + +/* enum qca_wlan_nan_subcmd_type - Type of NAN command used by attribute + * QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE as a part of vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. + */ +enum qca_wlan_nan_ext_subcmd_type { + /* Subcmd of type NAN Enable Request */ + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ = 1, + /* Subcmd of type NAN Disable Request */ + QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ = 2, +}; + +/** + * enum qca_wlan_vendor_attr_nan_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. + */ +enum qca_wlan_vendor_attr_nan_params { + QCA_WLAN_VENDOR_ATTR_NAN_INVALID = 0, + /* Carries NAN command for firmware component. Every vendor command + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT must contain this attribute with a + * payload containing the NAN command. NLA_BINARY attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA = 1, + /* Indicates the type of NAN command sent with + * QCA_NL80211_VENDOR_SUBCMD_NAN_EXT. enum qca_wlan_nan_ext_subcmd_type + * describes the possible range of values. This attribute is mandatory + * if the command being issued is either + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ or + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE = 2, + /* Frequency (in MHz) of primary NAN discovery social channel in 2.4 GHz + * band. This attribute is mandatory when command type is + * QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ = 3, + /* Frequency (in MHz) of secondary NAN discovery social channel in 5 GHz + * band. This attribute is optional and should be included when command + * type is QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ and NAN discovery + * has to be started on 5GHz along with 2.4GHz. NLA_U32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_AFTER_LAST - 1 +}; + +/** + * qca_wlan_twt_setup_state: Represents the TWT session states. + * + * QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED: TWT session not established. + * QCA_WLAN_TWT_SETUP_STATE_ACTIVE: TWT session is active. + * QCA_WLAN_TWT_SETUP_STATE_SUSPEND: TWT session is in suspended state. + */ +enum qca_wlan_twt_setup_state { + QCA_WLAN_TWT_SETUP_STATE_NOT_ESTABLISHED = 0, + QCA_WLAN_TWT_SETUP_STATE_ACTIVE = 1, + QCA_WLAN_TWT_SETUP_STATE_SUSPEND = 2, +}; + +/** + * enum qca_wlan_vendor_attr_twt_setup: Represents attributes for + * TWT (Target Wake Time) setup request. These attributes are sent as part of + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP and + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST: Flag attribute. + * Disable (flag attribute not present) - Individual TWT + * Enable (flag attribute present) - Broadcast TWT. + * Individual means the session is between the STA and the AP. + * This session is established using a separate negotiation between + * STA and AP. + * Broadcast means the session is across multiple STAs and an AP. The + * configuration parameters are announced in Beacon frames by the AP. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE: Required (u8). + * Unsigned 8-bit qca_wlan_vendor_twt_setup_req_type to + * specify the TWT request type. This is used in TWT SET operation. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER: Flag attribute + * Enable (flag attribute present) - TWT with trigger support. + * Disable (flag attribute not present) - TWT without trigger support. + * Trigger means the AP will send the trigger frame to allow STA to send data. + * Without trigger, the STA will wait for the MU EDCA timer before + * transmitting the data. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE: Required (u8) + * 0 - Announced TWT - In this mode, STA may skip few service periods to + * save more power. If STA wants to wake up, it will send a PS-POLL/QoS + * NULL frame to AP. + * 1 - Unannounced TWT - The STA will wakeup during every SP. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID: Optional (u8) + * Flow ID is the unique identifier for each TWT session. + * If not provided then dialog ID will be set to zero. + * This is an optional parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Request and Response + * 3. TWT TERMINATE Request and Response + * 4. TWT SUSPEND Request and Response + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions for the following + * 1. TWT TERMINATE Request and Response + * 2. TWT SUSPEND Request and Response + * 4. TWT CLEAR STATISTICS request + * 5. TWT GET STATISTICS request and response + * If an invalid dialog ID is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP: Required (u8) + * This attribute (exp) is used along with the mantissa to derive the + * wake interval using the following formula: + * pow(2,exp) = wake_intvl_us/wake_intvl_mantis + * Wake interval is the interval between 2 successive SP. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION: Flag attribute + * Enable (flag attribute present) - Protection required. + * Disable (flag attribute not present) - Protection not required. + * If protection is enabled, then the AP will use protection + * mechanism using RTS/CTS to self to reserve the airtime. + * This is used in + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME: Optional (u32) + * This attribute is used as the SP offset which is the offset from + * TSF after which the wake happens. The units are in microseconds. If + * this attribute is not provided, then the value will be set to zero. + * This is an optional parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION: Required (u32) + * This is the duration of the service period. This is specified as + * multiples of 256 microseconds. Valid values are 0x1 to 0xFF. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA: Required (u32) + * This attribute is used to configure wake interval mantissa. + * The units are in TU. + * This is a required parameter for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS: Required (u8) + * This field is applicable for TWT response only. + * This contains status values in enum qca_wlan_vendor_twt_status + * and is passed to the userspace. This is used in TWT SET operation. + * This is a required parameter for + * 1. TWT SET Response + * 2. TWT TERMINATE Response + * 3. TWT SUSPEND Response + * 4. TWT RESUME Response + * 5. TWT NUDGE Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE: Required (u8) + * This field is applicable for TWT response only. + * This field contains response type from the TWT responder and is + * passed to the userspace. The values for this field are defined in + * enum qca_wlan_vendor_twt_setup_resp_type. This is used in TWT SET + * response. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF: Required (u64) + * In TWT setup command this field contains absolute TSF that will + * be used by TWT requester during setup. + * In TWT response this field contains absolute TSF value of the + * wake time received from the TWT responder and is passed to + * the userspace. + * This is an optional parameter for + * 1. TWT SET Request + * This is a required parameter for + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED: Flag attribute. + * Enable (flag attribute present) - Indicates that the TWT responder + * supports reception of TWT information frame from the TWT requestor. + * Disable (flag attribute not present) - Indicates that the responder + * doesn't support reception of TWT information frame from requestor. + * This is used in + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which the TWT session + * is being configured. This is used in AP mode to represent the respective + * client. + * In AP mode, this is a required parameter in response for + * 1. TWT SET + * 2. TWT GET + * 3. TWT TERMINATE + * 4. TWT SUSPEND + * In STA mode, this is an optional parameter in request and response for + * the above four TWT operations. + * In AP mode, this is a required parameter in request for + * 1. TWT GET + * 2. TWT TERMINATE + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL: Optional (u32) + * Minimum tolerance limit of wake interval parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL: Optional (u32) + * Maximum tolerance limit of wake interval parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION: Optional (u32) + * Minimum tolerance limit of wake duration parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION: Optional (u32) + * Maximum tolerance limit of wake duration parameter in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE: Optional (u32) + * TWT state for the given dialog id. The values for this are represented + * by enum qca_wlan_twt_setup_state. + * This is obtained through TWT GET operation. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA: Optional (u32) + * This attribute is used to configure wake interval mantissa. + * The unit is microseconds. This attribute, when specified, takes + * precedence over QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA. + * This parameter is used for + * 1. TWT SET Request and Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID: Optional (u8) + * This attribute is used to configure Broadcast TWT ID. + * The Broadcast TWT ID indicates a specific Broadcast TWT for which the + * transmitting STA is providing TWT parameters. The allowed values are 0 to 31. + * This parameter is used for + * 1. TWT SET Request + * 2. TWT TERMINATE Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION: Optional (u8) + * This attribute is used to configure Broadcast TWT recommendation. + * The Broadcast TWT Recommendation subfield contains a value that indicates + * recommendations on the types of frames that are transmitted by TWT + * scheduled STAs and scheduling AP during the broadcast TWT SP. + * The allowed values are 0 - 3. + * This parameter is used for + * 1. TWT SET Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE: Optional (u8) + * This attribute is used to configure Broadcast TWT Persistence. + * The Broadcast TWT Persistence subfield indicates the number of + * TBTTs during which the Broadcast TWT SPs corresponding to this + * broadcast TWT Parameter set are present. The number of beacon intervals + * during which the Broadcast TWT SPs are present is equal to the value in the + * Broadcast TWT Persistence subfield plus 1 except that the value 255 + * indicates that the Broadcast TWT SPs are present until explicitly terminated. + * This parameter is used for + * 1. TWT SET Request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE: Optional (u8) + * This attribute contains the value of the Responder PM Mode subfield (0 or 1) + * from TWT response frame. + * This parameter is used for + * 1. TWT SET Response + * 2. TWT GET Response + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT: Optional (u32) + * This attribute is used to configure the announce timeout value (in us) in + * the firmware. This timeout value is only applicable for the announced TWT. If + * the timeout value is non-zero the firmware waits up to the timeout value to + * use Data frame as an announcement frame. If the timeout value is 0 the + * firmware sends an explicit QoS NULL frame as the announcement frame on SP + * start. The default value in the firmware is 0. + * This parameter is used for + * 1. TWT SET Request + */ +enum qca_wlan_vendor_attr_twt_setup { + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST = 1, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER = 3, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE = 4, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID = 5, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP = 6, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION = 7, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME = 8, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA = 10, + + /* TWT Response only attributes */ + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS = 11, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESP_TYPE = 12, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME_TSF = 13, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TWT_INFO_ENABLED = 14, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAC_ADDR = 15, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_INTVL = 16, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_INTVL = 17, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MIN_WAKE_DURATION = 18, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX_WAKE_DURATION = 19, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATE = 20, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL2_MANTISSA = 21, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID = 22, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION = 23, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE = 24, + + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_RESPONDER_PM_MODE = 25, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_ANNOUNCE_TIMEOUT = 26, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_SETUP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_twt_status - Represents the status of the requested + * TWT operation + * + * @QCA_WLAN_VENDOR_TWT_STATUS_OK: TWT request successfully completed + * @QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED: TWT not enabled + * @QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID: TWT dialog ID is already used + * @QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY: TWT session is busy + * @QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST: TWT session does not exist + * @QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED: TWT session not in suspend state + * @QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM: Invalid parameters + * @QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY: FW not ready + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE: FW resource exhausted + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK: Peer AP/STA did not ACK the + * request/response frame + * @QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE: Peer AP did not send the response + * frame + * @QCA_WLAN_VENDOR_TWT_STATUS_DENIED: AP did not accept the request + * @QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR: Adding TWT dialog failed due to an + * unknown reason + * @QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED: TWT session already in + * suspend state + * @QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID: FW has dropped the frame due to + * invalid IE in the received TWT frame + * @QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE: Parameters received from + * the responder are not in the specified range + * @QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE: FW terminated the TWT + * session due to request from the responder. Used on the TWT_TERMINATE + * notification from the firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE: FW terminated the TWT + * session due to roaming. Used on the TWT_TERMINATE notification from the + * firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE: FW terminated the + * TWT session due to SCC (Single Channel Concurrency) and MCC (Multi Channel + * Concurrency). Used on the TWT_TERMINATE notification from the firmware. + * @QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS: FW rejected the TWT setup + * request due to roaming in progress. + * @QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS: FW rejected the TWT + * setup request due to channel switch in progress. + * @QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS: FW rejected the TWT setup + * request due to scan in progress. + * QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE: The driver requested to + * terminate an existing TWT session on power save exit request from userspace. + * Used on the TWT_TERMINATE notification from the driver/firmware. + */ +enum qca_wlan_vendor_twt_status { + QCA_WLAN_VENDOR_TWT_STATUS_OK = 0, + QCA_WLAN_VENDOR_TWT_STATUS_TWT_NOT_ENABLED = 1, + QCA_WLAN_VENDOR_TWT_STATUS_USED_DIALOG_ID = 2, + QCA_WLAN_VENDOR_TWT_STATUS_SESSION_BUSY = 3, + QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST = 4, + QCA_WLAN_VENDOR_TWT_STATUS_NOT_SUSPENDED = 5, + QCA_WLAN_VENDOR_TWT_STATUS_INVALID_PARAM = 6, + QCA_WLAN_VENDOR_TWT_STATUS_NOT_READY = 7, + QCA_WLAN_VENDOR_TWT_STATUS_NO_RESOURCE = 8, + QCA_WLAN_VENDOR_TWT_STATUS_NO_ACK = 9, + QCA_WLAN_VENDOR_TWT_STATUS_NO_RESPONSE = 10, + QCA_WLAN_VENDOR_TWT_STATUS_DENIED = 11, + QCA_WLAN_VENDOR_TWT_STATUS_UNKNOWN_ERROR = 12, + QCA_WLAN_VENDOR_TWT_STATUS_ALREADY_SUSPENDED = 13, + QCA_WLAN_VENDOR_TWT_STATUS_IE_INVALID = 14, + QCA_WLAN_VENDOR_TWT_STATUS_PARAMS_NOT_IN_RANGE = 15, + QCA_WLAN_VENDOR_TWT_STATUS_PEER_INITIATED_TERMINATE = 16, + QCA_WLAN_VENDOR_TWT_STATUS_ROAM_INITIATED_TERMINATE = 17, + QCA_WLAN_VENDOR_TWT_STATUS_SCC_MCC_CONCURRENCY_TERMINATE = 18, + QCA_WLAN_VENDOR_TWT_STATUS_ROAMING_IN_PROGRESS = 19, + QCA_WLAN_VENDOR_TWT_STATUS_CHANNEL_SWITCH_IN_PROGRESS = 20, + QCA_WLAN_VENDOR_TWT_STATUS_SCAN_IN_PROGRESS = 21, + QCA_WLAN_VENDOR_TWT_STATUS_POWER_SAVE_EXIT_TERMINATE = 22, +}; + +/** + * enum qca_wlan_vendor_attr_twt_resume - Represents attributes for + * TWT (Target Wake Time) resume request. These attributes are sent as part of + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME and + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. Also used by + * attributes through %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT: Optional (u8) + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT: Optional (u32) + * These attributes are used as the SP offset which is the offset from TSF after + * which the wake happens. The units are in microseconds. Please note that + * _NEXT_TWT is limited to u8 whereas _NEXT2_TWT takes the u32 data. + * _NEXT2_TWT takes the precedence over _NEXT_TWT and thus the recommendation + * is to use _NEXT2_TWT. If neither of these attributes is provided, the value + * will be set to zero. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE: Required (u32) + * This attribute represents the next TWT subfield size. + * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits, + * and 4 for 64 bits. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID: Required (u8). + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session to resume. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions. + * If an invalid dialog id is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer to which TWT Resume is + * being sent. This is used in AP mode to represent the respective + * client and is a required parameter. In STA mode, this is an optional + * parameter + */ +enum qca_wlan_vendor_attr_twt_resume { + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT = 1, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE = 2, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID = 3, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT = 4, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAC_ADDR = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_RESUME_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_nudge - Represents attributes for + * TWT (Target Wake Time) nudge request. TWT nudge is a combination of suspend + * and resume in a single request. These attributes are sent as part of + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID: Required (u8) + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session to suspend and resume. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions in TWT NUDGE request + * and response. + * If an invalid dialog id is provided, status + * QCA_WLAN_VENDOR_TWT_STATUS_SESSION_NOT_EXIST will be returned. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME: Required (u32) + * This attribute is used as the SP offset which is the offset from + * TSF after which the wake happens. The units are in microseconds. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE: Required (u32) + * This attribute represents the next TWT subfield size. + * Value 0 represents 0 bits, 1 represents 32 bits, 2 for 48 bits, + * and 4 for 64 bits. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer to which TWT Suspend and Resume is + * being sent. This is used in AP mode to represent the respective + * client and is a required parameter. In STA mode, this is an optional + * parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF: Optional (u64) + * This field contains absolute TSF value of the time at which the TWT + * session will be resumed. + */ +enum qca_wlan_vendor_attr_twt_nudge { + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID = 1, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME = 2, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE = 3, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAC_ADDR = 4, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_stats: Represents attributes for + * TWT (Target Wake Time) get statistics and clear statistics request. + * These attributes are sent as part of + * %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID: Required (u8) + * Flow ID is the unique identifier for each TWT session. This attribute + * represents the respective TWT session for get and clear TWT statistics. + * Flow ID values from 0 to 254 represent a single TWT session + * Flow ID value of 255 represents all TWT sessions in + * 1) TWT GET STATISTICS request and response + * 2) TWT CLEAR STATISTICS request + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which TWT Statistics + * is required. + * In AP mode this is used to represent the respective + * client and is a required parameter for + * 1) TWT GET STATISTICS request and response + * 2) TWT CLEAR STATISTICS request and response + * In STA mode, this is an optional parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION: Required (u32) + * This is the duration of the service period in microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION: Required (u32) + * Average of the actual wake duration observed so far. Unit is microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS: Required (u32) + * The number of TWT service periods elapsed so far. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION: Required (u32) + * This is the minimum value of the wake duration observed across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is + * microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION: Required (u32) + * This is the maximum value of wake duration observed across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. Unit is + * microseconds. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU: Required (u32) + * Average number of MPDUs transmitted successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU: Required (u32) + * Average number of MPDUs received successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE: Required (u32) + * Average number of bytes transmitted successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE: Required (u32) + * Average number of bytes received successfully across + * QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS. + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS: Required (u32) + * Status of the TWT GET STATISTICS request. + * This contains status values in enum qca_wlan_vendor_twt_status + * Obtained in the QCA_WLAN_TWT_GET_STATS response from the firmware. + */ +enum qca_wlan_vendor_attr_twt_stats { + QCA_WLAN_VENDOR_ATTR_TWT_STATS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_FLOW_ID = 1, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAC_ADDR = 2, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_SESSION_WAKE_DURATION = 3, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVG_WAKE_DURATION = 4, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_NUM_SP_ITERATIONS = 5, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MIN_WAKE_DURATION = 6, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX_WAKE_DURATION = 7, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_MPDU = 8, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_MPDU = 9, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_TX_PACKET_SIZE = 10, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AVERAGE_RX_PACKET_SIZE = 11, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_STATUS = 12, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_STATS_AFTER_LAST - 1, +}; + +/** + * qca_wlan_twt_get_capa - Represents the bitmap of TWT capabilities + * supported by the device and the peer. + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_GET_CAPABILITIES + * + * @QCA_WLAN_TWT_CAPA_REQUESTOR: TWT requestor support is advertised by + * TWT non-scheduling STA. This capability is advertised in the HE + * Capability/Extended Capabilities information element in the + * Association Request frame by the device. + * + * @QCA_WLAN_TWT_CAPA_RESPONDER: TWT responder support is advertised by + * the TWT scheduling AP. This capability is advertised in the Extended + * Capabilities/HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_BROADCAST: On the requestor side, this indicates support + * for the broadcast TWT functionality. On the responder side, this indicates + * support for the role of broadcast TWT scheduling functionality. This + * capability is advertised in the HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_TWT_FLEXIBLE: The device supports flexible TWT schedule. + * This capability is advertised in the HE Capabilities information element. + * + * @QCA_WLAN_TWT_CAPA_REQUIRED: The TWT Required is advertised by AP to indicate + * that it mandates the associated HE STAs to support TWT. This capability is + * advertised by AP in the HE Operation Parameters field of the HE Operation + * information element. + */ +enum qca_wlan_twt_capa { + QCA_WLAN_TWT_CAPA_REQUESTOR = BIT(0), + QCA_WLAN_TWT_CAPA_RESPONDER = BIT(1), + QCA_WLAN_TWT_CAPA_BROADCAST = BIT(2), + QCA_WLAN_TWT_CAPA_FLEXIBLE = BIT(3), + QCA_WLAN_TWT_CAPA_REQUIRED = BIT(4), +}; + +/** + * enum qca_wlan_vendor_attr_twt_capability - Represents attributes for TWT + * get capabilities request type. Used by QCA_WLAN_TWT_GET_CAPABILITIES TWT + * operation. + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR: 6-byte MAC address + * Represents the MAC address of the peer for which the TWT capabilities + * are being queried. This is used in AP mode to represent the respective + * client. In STA mode, this is an optional parameter. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF: (u16). + * Self TWT capabilities. Carries a bitmap of TWT capabilities specified in + * enum qca_wlan_twt_capa. + * @QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER: (u16). + * Peer TWT capabilities. Carries a bitmap of TWT capabilities specified in + * enum qca_wlan_twt_capa. + */ +enum qca_wlan_vendor_attr_twt_capability { + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAC_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF = 2, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_twt_set_param: Represents attributes for + * TWT (Target Wake Time) related parameters. It is used when + * %QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION is set to %QCA_WLAN_TWT_SET_PARAM. + * These attributes are sent as part of %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT. + * + * @QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE: Optional (u8) + * This attribute configures AC parameters to be used for all TWT + * sessions in AP mode. + * Uses the enum qca_wlan_ac_type values. + */ +enum qca_wlan_vendor_attr_twt_set_param { + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AP_AC_VALUE = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_TWT_SET_PARAM_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_twt_setup_resp_type - Represents the response type by + * the TWT responder + * + * @QCA_WLAN_VENDOR_TWT_RESP_ALTERNATE: TWT responder suggests TWT + * parameters that are different from TWT requesting STA suggested + * or demanded TWT parameters + * @QCA_WLAN_VENDOR_TWT_RESP_DICTATE: TWT responder demands TWT + * parameters that are different from TWT requesting STA TWT suggested + * or demanded parameters + * @QCA_WLAN_VENDOR_TWT_RESP_REJECT: TWT responder rejects TWT + * setup + * @QCA_WLAN_VENDOR_TWT_RESP_ACCEPT: TWT responder accepts the TWT + * setup. + */ +enum qca_wlan_vendor_twt_setup_resp_type { + QCA_WLAN_VENDOR_TWT_RESP_ALTERNATE = 1, + QCA_WLAN_VENDOR_TWT_RESP_DICTATE = 2, + QCA_WLAN_VENDOR_TWT_RESP_REJECT = 3, + QCA_WLAN_VENDOR_TWT_RESP_ACCEPT = 4, +}; + +/** + * enum qca_wlan_vendor_twt_setup_req_type - Required (u8) + * Represents the setup type being requested for TWT. + * @QCA_WLAN_VENDOR_TWT_SETUP_REQUEST: STA is not specifying all the TWT + * parameters but relying on AP to fill the parameters during the negotiation. + * @QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST: STA will provide all the suggested + * values which the AP may accept or AP may provide alternative parameters + * which the STA may accept. + * @QCA_WLAN_VENDOR_TWT_SETUP_DEMAND: STA is not willing to accept any + * alternate parameters than the requested ones. + */ +enum qca_wlan_vendor_twt_setup_req_type { + QCA_WLAN_VENDOR_TWT_SETUP_REQUEST = 1, + QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST = 2, + QCA_WLAN_VENDOR_TWT_SETUP_DEMAND = 3, +}; + +/** + * enum qca_wlan_roam_scan_event_type - Type of roam scan event + * + * Indicates the type of roam scan event sent by firmware/driver. + * + * @QCA_WLAN_ROAM_SCAN_TRIGGER_EVENT: Roam scan trigger event type. + * @QCA_WLAN_ROAM_SCAN_STOP_EVENT: Roam scan stopped event type. + */ +enum qca_wlan_roam_scan_event_type { + QCA_WLAN_ROAM_SCAN_TRIGGER_EVENT = 0, + QCA_WLAN_ROAM_SCAN_STOP_EVENT = 1, +}; + +/** + * enum qca_wlan_roam_scan_trigger_reason - Roam scan trigger reason + * + * Indicates the reason for triggering roam scan by firmware/driver. + * + * @QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_LOW_RSSI: Due to low RSSI of current AP. + * @QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_HIGH_PER: Due to high packet error rate. + */ +enum qca_wlan_roam_scan_trigger_reason { + QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_LOW_RSSI = 0, + QCA_WLAN_ROAM_SCAN_TRIGGER_REASON_HIGH_PER = 1, +}; + +/** + * enum qca_wlan_vendor_attr_roam_scan - Vendor subcmd attributes to report + * roam scan related details from driver/firmware to user space. enum values + * are used for NL attributes sent with + * %QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT sub command. + */ +enum qca_wlan_vendor_attr_roam_scan { + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_INVALID = 0, + /* Encapsulates type of roam scan event being reported. enum + * qca_wlan_roam_scan_event_type describes the possible range of + * values. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_EVENT_TYPE = 1, + /* Encapsulates reason for triggering roam scan. enum + * qca_wlan_roam_scan_trigger_reason describes the possible range of + * values. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_TRIGGER_REASON = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_SCAN_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_cfr_data_transport_modes - Defines QCA vendor CFR data + * transport modes and is used by the attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE as a part of the vendor + * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. + * @QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS: Use relayfs to send CFR data. + * @QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS: Use netlink events to send CFR + * data. The data shall be encapsulated within + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA along with the vendor sub command + * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an asynchronous event. + */ +enum qca_wlan_vendor_cfr_data_transport_modes { + QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS = 0, + QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS = 1, +}; + +/** + * enum qca_wlan_vendor_cfr_method - QCA vendor CFR methods used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD as part of vendor + * command QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG. + * @QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL: CFR method using QoS Null frame + * @QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE: CFR method using QoS Null frame + * with phase + * @QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE: CFR method using Probe Response frame + */ +enum qca_wlan_vendor_cfr_method { + QCA_WLAN_VENDOR_CFR_METHOD_QOS_NULL = 0, + QCA_WLAN_VENDOR_CFR_QOS_NULL_WITH_PHASE = 1, + QCA_WLAN_VENDOR_CFR_PROBE_RESPONSE = 2, +}; + +/** + * enum qca_wlan_vendor_cfr_capture_type - QCA vendor CFR capture type used by + * attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE. + * @QCA_WLAN_VENDOR_CFR_DIRECT_FTM: Filter directed FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK: Filter all FTM ACK frames. + * @QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP: Filter NDPA NDP directed frames. + * @QCA_WLAN_VENDOR_CFR_TA_RA: Filter frames based on TA/RA/Subtype which + * is provided by one or more of below attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * @QCA_WLAN_CFR_ALL_PACKET: Filter all packets. + * @QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL: Filter all NDPA NDP frames. + */ +enum qca_wlan_vendor_cfr_capture_type { + QCA_WLAN_VENDOR_CFR_DIRECT_FTM = 0, + QCA_WLAN_VENDOR_CFR_ALL_FTM_ACK = 1, + QCA_WLAN_VENDOR_CFR_DIRECT_NDPA_NDP = 2, + QCA_WLAN_VENDOR_CFR_TA_RA = 3, + QCA_WLAN_VENDOR_CFR_ALL_PACKET = 4, + QCA_WLAN_VENDOR_CFR_NDPA_NDP_ALL = 5, +}; + +/** + * enum qca_wlan_vendor_peer_cfr_capture_attr - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG to configure peer + * Channel Frequency Response capture parameters and enable periodic CFR + * capture. + * + * @QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR: Optional (6-byte MAC address) + * MAC address of peer. This is for CFR version 1 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE: Required (flag) + * Enable peer CFR capture. This attribute is mandatory to enable peer CFR + * capture. If this attribute is not present, peer CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH: Optional (u8) + * BW of measurement, attribute uses the values in enum nl80211_chan_width + * Supported values: 20, 40, 80, 80+80, 160. + * Note that all targets may not support all bandwidths. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY: Optional (u32) + * Periodicity of CFR measurement in milliseconds. + * Periodicity should be a multiple of Base timer. + * Current Base timer value supported is 10 milliseconds (default). + * 0 for one shot capture. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD: Optional (u8) + * Method used to capture Channel Frequency Response. + * Attribute uses the values defined in enum qca_wlan_vendor_cfr_method. + * This attribute is mandatory for version 1 if attribute + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE is used. + * + * @QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE: Optional (flag) + * Enable periodic CFR capture. + * This attribute is mandatory for version 1 to enable Periodic CFR capture. + * If this attribute is not present, periodic CFR capture is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION: Optional (u8) + * Value is 1 or 2 since there are two versions of CFR capture. Two versions + * can't be enabled at same time. This attribute is mandatory if target + * support both versions and use one of them. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP: Optional (u32) + * This attribute is mandatory for version 2 if + * QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY is used. + * Bits 15:0 bitfield indicates which group is to be enabled. + * Bits 31:16 Reserved for future use. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION: Optional (u32) + * CFR capture duration in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL: Optional (u32) + * CFR capture interval in microsecond. This attribute is mandatory for + * version 2 if attribute QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION is used. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE: Optional (u32) + * CFR capture type is defined in enum qca_wlan_vendor_cfr_capture_type. + * This attribute is mandatory for version 2. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK: Optional (u64) + * Bitfield indicating which user in the current UL MU transmissions are + * enabled for CFR capture. Bits 36 to 0 indicate user indexes for 37 users in + * a UL MU transmission. If bit 0 is set, the CFR capture will happen for user + * index 0 in the current UL MU transmission. If bits 0 and 2 are set, CFR + * capture for UL MU TX corresponds to user indices 0 and 2. Bits 63:37 are + * reserved for future use. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT: Optional (u32) + * Indicates the number of consecutive RX frames to be skipped before CFR + * capture is enabled again. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE: Nested attribute containing + * one or more %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY attributes. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY: Nested attribute containing + * the following group attributes: + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER, + * %QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER: Optional (u32) + * Target supports multiple groups for some configurations. The group number + * can be any value between 0 and 15. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA: Optional (6-byte MAC address) + * Transmitter address which is used to filter frames. This MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA: Optional (6-byte MAC address) + * Receiver address which is used to filter frames. This MAC address takes + * effect with QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK: Optional (6-byte MAC address) + * Mask of transmitter address which is used to filter frames. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK: Optional (6-byte MAC address) + * Mask of receiver address which is used to filter frames. This is for CFR + * version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS: Optional (u32) + * Indicates frames with a specific NSS will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 7:0 request CFR + * capture to be done for frames matching the NSS specified within this bitmask. + * Bits 31:8 are reserved for future use. Bits 7:0 map to NSS: + * bit 0 : NSS 1 + * bit 1 : NSS 2 + * ... + * bit 7 : NSS 8 + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW: Optional (u32) + * Indicates frames with a specific bandwidth will be filtered for CFR capture. + * This is for CFR version 2 only. This is a bitmask. Bits 4:0 request CFR + * capture to be done for frames matching the bandwidths specified within this + * bitmask. Bits 31:5 are reserved for future use. Bits 4:0 map to bandwidth + * numerated in enum nl80211_band (although not all bands may be supported + * by a given device). + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER: Optional (u32) + * Management frames matching the subtype filter categories will be filtered in + * by MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Management frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. For example, Beacon frame control type + * is 8 and its value is 1 << 8 = 0x100. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER: Optional (u32) + * Control frames matching the subtype filter categories will be filtered in by + * MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Control frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER: Optional (u32) + * Data frames matching the subtype filter categories will be filtered in by + * MAC for CFR capture. This is a bitmask in which each bit represents the + * corresponding Data frame subtype value per IEEE Std 802.11-2016, + * 9.2.4.1.3 Type and Subtype subfields. This is for CFR version 2 only. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE: Optional (u8) + * Userspace can use this attribute to specify the driver about which transport + * mode shall be used by the driver to send CFR data to userspace. Uses values + * from enum qca_wlan_vendor_cfr_data_transport_modes. When this attribute is + * not present, the driver shall use the default transport mechanism which is + * QCA_WLAN_VENDOR_CFR_DATA_RELAY_FS. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID: Optional (u32) + * Userspace can use this attribute to specify the nl port id of the application + * which receives the CFR data and processes it further so that the drivers can + * unicast the netlink events to a specific application. Optionally included + * when QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE is set to + * QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS, not required otherwise. The drivers + * shall multicast the netlink events when this attribute is not included. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA: Required (NLA_BINARY). + * This attribute will be used by the driver to encapsulate and send CFR data + * to userspace along with QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG as an + * asynchronous event when the driver is configured to send CFR data using + * netlink events with %QCA_WLAN_VENDOR_CFR_DATA_NETLINK_EVENTS. + */ +enum qca_wlan_vendor_peer_cfr_capture_attr { + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CFR_PEER_MAC_ADDR = 1, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE = 2, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_BANDWIDTH = 3, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_PERIODICITY = 4, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_METHOD = 5, + QCA_WLAN_VENDOR_ATTR_PERIODIC_CFR_CAPTURE_ENABLE = 6, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_VERSION = 7, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_ENABLE_GROUP_BITMAP = 8, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DURATION = 9, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_INTERVAL = 10, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_CAPTURE_TYPE = 11, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_UL_MU_MASK = 12, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_FREEZE_TLV_DELAY_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TABLE = 14, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_ENTRY = 15, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NUMBER = 16, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA = 17, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA = 18, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_TA_MASK = 19, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_RA_MASK = 20, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_NSS = 21, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_BW = 22, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_MGMT_FILTER = 23, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_CTRL_FILTER = 24, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_GROUP_DATA_FILTER = 25, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_TRANSPORT_MODE = 26, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_DATA_RECEIVER_PID = 27, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_RESP_DATA = 28, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_PEER_CFR_MAX = + QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_throughput_level - Current throughput level + * + * Indicates the current level of throughput calculated by the driver. The + * driver may choose different thresholds to decide whether the throughput level + * is low or medium or high based on variety of parameters like physical link + * capacity of the current connection, the number of packets being dispatched + * per second, etc. The throughput level events might not be consistent with the + * actual current throughput value being observed. + * + * @QCA_WLAN_THROUGHPUT_LEVEL_LOW: Low level of throughput + * @QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM: Medium level of throughput + * @QCA_WLAN_THROUGHPUT_LEVEL_HIGH: High level of throughput + */ +enum qca_wlan_throughput_level { + QCA_WLAN_THROUGHPUT_LEVEL_LOW = 0, + QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM = 1, + QCA_WLAN_THROUGHPUT_LEVEL_HIGH = 2, +}; + +/** + * enum qca_wlan_vendor_attr_throughput_change - Vendor subcmd attributes to + * report throughput changes from the driver to user space. enum values are used + * for netlink attributes sent with + * %QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT sub command. + */ +enum qca_wlan_vendor_attr_throughput_change { + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_INVALID = 0, + /* Indicates the direction of throughput in which the change is being + * reported. u8 attribute. Value is 0 for TX and 1 for RX. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION = 1, + /* Indicates the newly observed throughput level. enum + * qca_wlan_throughput_level describes the possible range of values. + * u8 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL = 2, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_limit_output_bytes. u32 attribute. The + * driver may optionally include this attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES = 3, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_adv_win_scale. s8 attribute. Possible + * values are from -31 to 31. The driver may optionally include this + * attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE = 4, + /* Indicates the driver's guidance on the new value to be set to + * kernel's TCP parameter tcp_delack_seg. u32 attribute. The driver may + * optionally include this attribute. + */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX = + QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST - 1, +}; + +/** + * enum qca_coex_config_profiles - This enum defines different types of + * traffic streams that can be prioritized one over the other during coex + * scenarios. + * The types defined in this enum are categorized in the below manner. + * 0 - 31 values corresponds to WLAN + * 32 - 63 values corresponds to BT + * 64 - 95 values corresponds to Zigbee + * @QCA_WIFI_STA_DISCOVERY: Prioritize discovery frames for WLAN STA + * @QCA_WIFI_STA_CONNECTION: Prioritize connection frames for WLAN STA + * @QCA_WIFI_STA_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN STA + * @QCA_WIFI_STA_DATA : Prioritize data frames for WLAN STA + * @QCA_WIFI_STA_ALL: Priritize all frames for WLAN STA + * @QCA_WIFI_SAP_DISCOVERY: Prioritize discovery frames for WLAN SAP + * @QCA_WIFI_SAP_CONNECTION: Prioritize connection frames for WLAN SAP + * @QCA_WIFI_SAP_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN SAP + * @QCA_WIFI_SAP_DATA: Prioritize data frames for WLAN SAP + * @QCA_WIFI_SAP_ALL: Prioritize all frames for WLAN SAP + * @QCA_BT_A2DP: Prioritize BT A2DP + * @QCA_BT_BLE: Prioritize BT BLE + * @QCA_BT_SCO: Prioritize BT SCO + * @QCA_ZB_LOW: Prioritize Zigbee Low + * @QCA_ZB_HIGH: Prioritize Zigbee High + */ +enum qca_coex_config_profiles { + /* 0 - 31 corresponds to WLAN */ + QCA_WIFI_STA_DISCOVERY = 0, + QCA_WIFI_STA_CONNECTION = 1, + QCA_WIFI_STA_CLASS_3_MGMT = 2, + QCA_WIFI_STA_DATA = 3, + QCA_WIFI_STA_ALL = 4, + QCA_WIFI_SAP_DISCOVERY = 5, + QCA_WIFI_SAP_CONNECTION = 6, + QCA_WIFI_SAP_CLASS_3_MGMT = 7, + QCA_WIFI_SAP_DATA = 8, + QCA_WIFI_SAP_ALL = 9, + QCA_WIFI_CASE_MAX = 31, + /* 32 - 63 corresponds to BT */ + QCA_BT_A2DP = 32, + QCA_BT_BLE = 33, + QCA_BT_SCO = 34, + QCA_BT_CASE_MAX = 63, + /* 64 - 95 corresponds to Zigbee */ + QCA_ZB_LOW = 64, + QCA_ZB_HIGH = 65, + QCA_ZB_CASE_MAX = 95, + /* 0xff is default value if the u8 profile value is not set. */ + QCA_COEX_CONFIG_PROFILE_DEFAULT_VALUE = 255 +}; + +/** + * enum qca_vendor_attr_coex_config_types - Coex configurations types. + * This enum defines the valid set of values of coex configuration types. These + * values may used by attribute + * %QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE. + * + * @QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_RESET: Reset all the + * weights to default values. + * @QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_START: Start to config + * weights with configurability value. + */ +enum qca_vendor_attr_coex_config_types { + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_RESET = 1, + QCA_WLAN_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_COEX_START = 2, +}; + +/** + * enum qca_vendor_attr_coex_config - Specifies vendor coex config attributes + * + * @QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES: This attribute contains variable + * length array of 8-bit values from enum qca_coex_config_profiles. + * FW will prioritize the profiles in the order given in the array encapsulated + * in this attribute. + * For example: + * ----------------------------------------------------------------------- + * | 1 | 34 | 32 | 65 | + * ----------------------------------------------------------------------- + * If the attribute contains the values defined in above array then it means + * 1) Wifi STA connection has priority over BT_SCO, BT_A2DP and ZIGBEE HIGH. + * 2) BT_SCO has priority over BT_A2DP. + * 3) BT_A2DP has priority over ZIGBEE HIGH. + * Profiles which are not listed in this array shall not be preferred over the + * profiles which are listed in the array as a part of this attribute. + */ +enum qca_vendor_attr_coex_config { + QCA_VENDOR_ATTR_COEX_CONFIG_INVALID = 0, + QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES = 1, + + /* Keep last */ + QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST, + QCA_VENDOR_ATTR_COEX_CONFIG_MAX = + QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_coex_config_three_way - Specifies vendor coex config + * attributes + * Attributes for data used by QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG + * + * QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE: u32 attribute. + * Indicate config type. + * The config types are 32-bit values from qca_vendor_attr_coex_config_types + * + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1: u32 attribute. + * Indicate the Priority 1 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2: u32 attribute. + * Indicate the Priority 2 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3: u32 attribute. + * Indicate the Priority 3 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * @QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4: u32 attribute. + * Indicate the Priority 4 profiles. + * The profiles are 8-bit values from enum qca_coex_config_profiles. + * In same priority level, maximum to 4 profiles can be set here. + * NOTE: + * Limitations for QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_x priority + * arrangement: + * 1: In the same u32 attribute (priority x), the profiles enum values own + * same priority level. + * 2: 0xff is default value if the u8 profile value is not set. + * 3: max to 4 rules/profiles in same priority level. + * 4: max to 4 priority level (priority 1 - priority 4) + * 5: one priority level only supports one scenario from WLAN/BT/ZB, + * hybrid rules not support. + * 6: if WMI_COEX_CONFIG_THREE_WAY_COEX_RESET called, priority x will + * remain blank to reset all parameters. + * For example: + * + * If the attributes as follow: + * priority 1: + * ------------------------------------ + * | 0xff | 0 | 1 | 2 | + * ------------------------------------ + * priority 2: + * ------------------------------------- + * | 0xff | 0xff | 0xff | 32 | + * ------------------------------------- + * priority 3: + * ------------------------------------- + * | 0xff | 0xff | 0xff | 65 | + * ------------------------------------- + * then it means: + * 1: WIFI_STA_DISCOVERY, WIFI_STA_CLASS_3_MGMT and WIFI_STA_CONNECTION + * owns same priority level. + * 2: WIFI_STA_DISCOVERY, WIFI_STA_CLASS_3_MGMT and WIFI_STA_CONNECTION + * has priority over BT_A2DP and ZB_HIGH. + * 3: BT_A2DP has priority over ZB_HIGH. + */ +enum qca_vendor_attr_coex_config_three_way { + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_INVALID = 0, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_CONFIG_TYPE = 1, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_1 = 2, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_2 = 3, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_3 = 4, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_PRIORITY_4 = 5, + + /* Keep last */ + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_AFTER_LAST, + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_MAX = + QCA_VENDOR_ATTR_COEX_CONFIG_THREE_WAY_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_link_properties - Represent the link properties. + * + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR: MAC address of the peer + * (STA/AP) for the connected link. + * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS: Attribute containing a + * &struct nl80211_sta_flag_update for the respective connected link. MAC + * address of the peer represented by + * QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR. + */ +enum qca_wlan_vendor_attr_link_properties { + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0, + /* 1 - 3 are reserved */ + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR = 4, + QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS = 5, + + /* Keep last */ + QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST, + QCA_VENDOR_ATTR_LINK_PROPERTIES_MAX = + QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1, +}; + +/** + * enum qca_vendor_attr_peer_stats_cache_type - Represents peer stats cache type + * This enum defines the valid set of values of peer stats cache types. These + * values are used by attribute + * %QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_TX_RATE_STATS: Represents peer TX rate statistics + * @QCA_WLAN_VENDOR_ATTR_PEER_RX_RATE_STATS: Represents peer RX rate statistics + * @QCA_WLAN_VENDOR_ATTR_PEER_TX_SOJOURN_STATS: Represents peer TX sojourn + * statistics + */ +enum qca_vendor_attr_peer_stats_cache_type { + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_PEER_TX_RATE_STATS, + QCA_WLAN_VENDOR_ATTR_PEER_RX_RATE_STATS, + QCA_WLAN_VENDOR_ATTR_PEER_TX_SOJOURN_STATS, +}; + +/** + * enum qca_wlan_vendor_attr_peer_stats_cache_params - This enum defines + * attributes required for QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH + * Information in these attributes is used to flush peer rate statistics from + * the driver to user application. + * + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE: Unsigned 32-bit attribute + * Indicate peer statistics cache type. + * The statistics types are 32-bit values from + * enum qca_vendor_attr_peer_stats_cache_type. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC: Unsigned 8-bit array + * of size 6 octets, representing the peer MAC address. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA: Opaque data attribute + * containing buffer of statistics to send to application layer entity. + * @QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE: Unsigned 64-bit attribute + * representing a cookie for peer unique session. + */ +enum qca_wlan_vendor_attr_peer_stats_cache_params { + QCA_WLAN_VENDOR_ATTR_PEER_STATS_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC = 2, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA = 3, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE = 4, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_LAST, + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX = + QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_LAST - 1 +}; + +/** + * enum qca_mpta_helper_attr_zigbee_state - Current Zigbee state + * This enum defines all the possible states of Zigbee, which can be + * delivered in the QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_STATE attribute. + * + * @ZIGBEE_IDLE: Zigbee in idle state + * @ZIGBEE_FORM_NETWORK: Zigbee forming network + * @ZIGBEE_WAIT_JOIN: Zigbee waiting for joining network + * @ZIGBEE_JOIN: Zigbee joining network + * @ZIGBEE_NETWORK_UP: Zigbee network is up + * @ZIGBEE_HMI: Zigbee in HMI mode + */ +enum qca_mpta_helper_attr_zigbee_state { + ZIGBEE_IDLE = 0, + ZIGBEE_FORM_NETWORK = 1, + ZIGBEE_WAIT_JOIN = 2, + ZIGBEE_JOIN = 3, + ZIGBEE_NETWORK_UP = 4, + ZIGBEE_HMI = 5, +}; + +/* + * enum qca_mpta_helper_vendor_attr - Attributes used in vendor sub-command + * QCA_NL80211_VENDOR_SUBCMD_MPTA_HELPER_CONFIG. + */ +enum qca_mpta_helper_vendor_attr { + QCA_MPTA_HELPER_VENDOR_ATTR_INVALID = 0, + /* Optional attribute used to update Zigbee state. + * enum qca_mpta_helper_attr_zigbee_state. + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_STATE = 1, + /* Optional attribute used to configure WLAN duration for Shape-OCS + * during interrupt. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_NON_WLAN_DURATION. + * Value range 0 ~ 300 (ms). + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_WLAN_DURATION = 2, + /* Optional attribute used to configure non-WLAN duration for Shape-OCS + * during interrupt. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_WLAN_DURATION. + * Value range 0 ~ 300 (ms). + * NLA_U32 attribute. + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_NON_WLAN_DURATION = 3, + /* Optional attribute used to configure WLAN duration for Shape-OCS + * monitor period. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_NON_WLAN_DURATION. + * Value range 0 ~ 300 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_WLAN_DURATION = 4, + /* Optional attribute used to configure non-WLAN duration for Shape-OCS + * monitor period. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_WLAN_DURATION. + * Value range 0 ~ 300 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_NON_WLAN_DURATION = 5, + /* Optional attribute used to configure OCS interrupt duration. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_MON_OCS_DURATION. + * Value range 1000 ~ 20000 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_INT_OCS_DURATION = 6, + /* Optional attribute used to configure OCS monitor duration. + * Set in pair with QCA_MPTA_HELPER_VENDOR_ATTR_INT_OCS_DURATION. + * Value range 1000 ~ 20000 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_MON_OCS_DURATION = 7, + /* Optional attribute used to notify WLAN firmware the current Zigbee + * channel. + * Value range 11 ~ 26 + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_ZIGBEE_CHAN = 8, + /* Optional attribute used to configure WLAN mute duration. + * Value range 0 ~ 400 (ms) + * NLA_U32 attribute + */ + QCA_MPTA_HELPER_VENDOR_ATTR_WLAN_MUTE_DURATION = 9, + + /* keep last */ + QCA_MPTA_HELPER_VENDOR_ATTR_AFTER_LAST, + QCA_MPTA_HELPER_VENDOR_ATTR_MAX = + QCA_MPTA_HELPER_VENDOR_ATTR_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_beacon_reporting_op_types - Defines different types of + * operations for which %QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING can be used. + * Will be used by %QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE. + * + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START: Sent by userspace to the driver + * to request the driver to start reporting Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_STOP: Sent by userspace to the driver to + * request the driver to stop reporting Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO: Sent by the driver to + * userspace to report received Beacon frames. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE: Sent by the driver to userspace + * to indicate that the driver is going to pause reporting Beacon frames. + */ +enum qca_wlan_vendor_beacon_reporting_op_types { + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START = 0, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_STOP = 1, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO = 2, + QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE = 3, +}; + +/** + * enum qca_wlan_vendor_beacon_reporting_pause_reasons - Defines different types + * of reasons for which the driver is pausing reporting Beacon frames. Will be + * used by %QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON. + * + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_UNSPECIFIED: For unspecified + * reasons. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_SCAN_STARTED: When the + * driver/firmware is starting a scan. + * @QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED: When the + * driver/firmware disconnects from the ESS and indicates the disconnection to + * userspace (non-seamless roaming case). This reason code will be used by the + * driver/firmware to indicate stopping of beacon report events. Userspace will + * need to start beacon reporting again (if desired) by sending vendor command + * QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING with + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START after the next connection is + * completed. + */ +enum qca_wlan_vendor_beacon_reporting_pause_reasons { + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_UNSPECIFIED = 0, + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_SCAN_STARTED = 1, + QCA_WLAN_VENDOR_BEACON_REPORTING_PAUSE_REASON_DISCONNECTED = 2, +}; + +/* + * enum qca_wlan_vendor_attr_beacon_reporting_params - List of attributes used + * in vendor sub-command QCA_NL80211_VENDOR_SUBCMD_BEACON_REPORTING. + */ +enum qca_wlan_vendor_attr_beacon_reporting_params { + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_INVALID = 0, + /* Specifies the type of operation that the vendor command/event is + * intended for. Possible values for this attribute are defined in + * enum qca_wlan_vendor_beacon_reporting_op_types. u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE = 1, + /* Optionally set by userspace to request the driver to report Beacon + * frames using asynchronous vendor events when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. NLA_FLAG attribute. + * If this flag is not set, the driver will only update Beacon frames in + * cfg80211 scan cache but not send any vendor events. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_ACTIVE_REPORTING = 2, + /* Optionally used by userspace to request the driver/firmware to report + * Beacon frames periodically when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. + * u32 attribute, indicates the period of Beacon frames to be reported + * and in the units of beacon interval. + * If this attribute is missing in the command, then the default value + * of 1 will be assumed by driver, i.e., to report every Beacon frame. + * Zero is an invalid value. + * If a valid value is received for this attribute, the driver will + * update the cfg80211 scan cache periodically as per the value received + * in this attribute in addition to updating the cfg80211 scan cache + * when there is significant change in Beacon frame IEs. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PERIOD = 3, + /* Used by the driver to encapsulate the SSID when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u8 array with a maximum size of 32. + * + * When generating beacon report from non-MBSSID Beacon frame, the SSID + * will be taken from the SSID element of the received Beacon frame. + * + * When generating beacon report from Multiple BSSID Beacon frame and if + * the BSSID of the current connected BSS matches the BSSID of the + * transmitting BSS, the SSID will be taken from the SSID element of the + * received Beacon frame. + * + * When generating beacon report from Multiple BSSID Beacon frame and if + * the BSSID of the current connected BSS matches the BSSID of one of + * the* nontransmitting BSSs, the SSID will be taken from the SSID field + * included in the nontransmitted BSS profile whose derived BSSID is + * same as the BSSID of the current connected BSS. When there is no + * nontransmitted BSS profile whose derived BSSID is same as the BSSID + * of current connected* BSS, this attribute will not be present. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_SSID = 4, + /* Used by the driver to encapsulate the BSSID of the AP to which STA is + * currently connected to when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u8 array with a + * fixed size of 6 bytes. + * + * When generating beacon report from a Multiple BSSID beacon and the + * current connected BSSID matches one of the nontransmitted BSSIDs in a + * Multiple BSSID set, this BSSID will be that particular nontransmitted + * BSSID and not the transmitted BSSID (i.e., the transmitting address + * of the Beacon frame). + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BSSID = 5, + /* Used by the driver to encapsulate the frequency in MHz on which + * the Beacon frame was received when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is + * set to QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_FREQ = 6, + /* Used by the driver to encapsulate the Beacon interval + * when the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u16 attribute. The value will be copied from the Beacon frame and the + * units are TUs. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BI = 7, + /* Used by the driver to encapsulate the Timestamp field from the Beacon + * frame when the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set + * to QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. + * u64 attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_TSF = 8, + /* Used by the driver to encapsulate the CLOCK_BOOTTIME when this + * Beacon frame is received in the driver when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u64 attribute, in + * the units of nanoseconds. This value is expected to have accuracy of + * about 10 ms. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_BOOTTIME_WHEN_RECEIVED = 9, + /* Used by the driver to encapsulate the IEs of the Beacon frame from + * which this event is generated when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_BEACON_INFO. u8 array. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_IES = 10, + /* Used by the driver to specify the reason for the driver/firmware to + * pause sending beacons to userspace when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE. Possible values are + * defined in enum qca_wlan_vendor_beacon_reporting_pause_reasons, u32 + * attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_PAUSE_REASON = 11, + /* Used by the driver to specify whether the driver will automatically + * resume reporting beacon events to userspace later (for example after + * the ongoing off-channel activity is completed etc.) when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE. NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES = 12, + /* Optionally set by userspace to request the driver not to resume + * beacon reporting after a pause is completed, when the + * QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_OP_TYPE is set to + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START. NLA_FLAG attribute. + * If this flag is set, the driver will not resume beacon reporting + * after any pause in beacon reporting is completed. Userspace has to + * send QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START command again in order + * to initiate beacon reporting again. If this flag is set in the recent + * QCA_WLAN_VENDOR_BEACON_REPORTING_OP_START command, then in the + * subsequent QCA_WLAN_VENDOR_BEACON_REPORTING_OP_PAUSE event (if any) + * the QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_AUTO_RESUMES shall not be + * set by the driver. Setting this flag until and unless there is a + * specific need is not recommended as there is a chance of some beacons + * received after pause command and next start command being not + * reported. + */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_DO_NOT_RESUME = 13, + + /* Keep last */ + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_LAST, + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_MAX = + QCA_WLAN_VENDOR_ATTR_BEACON_REPORTING_LAST - 1 +}; + +/** + * enum qca_vendor_interop_issues_ap_type - Interop issue types + * This enum defines the valid set of values of interop issue types. These + * values are used by attribute %QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE. + * + * @QCA_VENDOR_INTEROP_ISSUES_AP_ON_STA_PS: The AP has power save interop issue + * when the STA's Qpower feature is enabled. + */ +enum qca_vendor_interop_issues_ap_type { + QCA_VENDOR_INTEROP_ISSUES_AP_INVALID = 0, + QCA_VENDOR_INTEROP_ISSUES_AP_ON_STA_PS = 1, +}; + +/** + * enum qca_vendor_attr_interop_issues_ap - attribute for AP with interop issues + * Values are used by %QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP. + * + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_INVALID: Invalid value + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE: Interop issue type + * 32-bit unsigned value. The values defined in enum + * qca_vendor_interop_issues_ap_type are used. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST: APs' BSSID container + * array of nested QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID attributes. + * It is present and mandatory for the command but is not used for the event + * since only a single BSSID is reported in an event. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID: AP's BSSID 6-byte MAC address. + * It is used within the nested QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST + * attribute in command case and without such encapsulation in the event case. + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST: last value + * @QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX: max value + */ +enum qca_vendor_attr_interop_issues_ap { + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_INVALID, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX = + QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_AFTER_LAST - 1 +}; + +/** + * enum qca_vendor_oem_device_type - Represents the target device in firmware. + * It is used by QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO. + * + * @QCA_VENDOR_OEM_DEVICE_VIRTUAL: The command is intended for + * a virtual device. + * + * @QCA_VENDOR_OEM_DEVICE_PHYSICAL: The command is intended for + * a physical device. + */ +enum qca_vendor_oem_device_type { + QCA_VENDOR_OEM_DEVICE_VIRTUAL = 0, + QCA_VENDOR_OEM_DEVICE_PHYSICAL = 1, +}; + +/** + * enum qca_wlan_vendor_attr_oem_data_params - Used by the vendor command/event + * QCA_NL80211_VENDOR_SUBCMD_OEM_DATA. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA: This NLA_BINARY attribute is + * used to set/query the data to/from the firmware. On query, the same + * attribute is used to carry the respective data in the reply sent by the + * driver to userspace. The request to set/query the data and the format of the + * respective data from the firmware are embedded in the attribute. The + * maximum size of the attribute payload is 1024 bytes. + * Userspace has to set the QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED + * attribute when the data is queried from the firmware. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO: The binary blob will be routed + * based on this field. This optional attribute is included to specify whether + * the device type is a virtual device or a physical device for the + * command/event. This attribute can be omitted for a virtual device (default) + * command/event. + * This u8 attribute is used to carry information for the device type using + * values defined by enum qca_vendor_oem_device_type. + * + * @QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED: This NLA_FLAG attribute + * is set when the userspace queries data from the firmware. This attribute + * should not be set when userspace sets the OEM data to the firmware. + */ +enum qca_wlan_vendor_attr_oem_data_params { + QCA_WLAN_VENDOR_ATTR_OEM_DATA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_CMD_DATA = 1, + QCA_WLAN_VENDOR_ATTR_OEM_DEVICE_INFO = 2, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_RESPONSE_EXPECTED = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_OEM_DATA_PARAMS_AFTER_LAST - 1 +}; + +/** + * enum qca_wlan_vendor_attr_avoid_frequency_ext - Defines attributes to be + * used with vendor command/event QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_EXT. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE: Required + * Nested attribute containing multiple ranges with following attributes: + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START, + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END, and + * QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START: Required (u32) + * Starting center frequency in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END: Required (u32) + * Ending center frequency in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM: + * s32 attribute, optional. It is a per frequency range attribute. + * The maximum TX power limit from user space is to be applied on an + * unrestricted interface for corresponding frequency range. It is also + * possible that the actual TX power may be even lower than this cap due to + * other considerations such as regulatory compliance, SAR, etc. In absence of + * this attribute the driver shall follow current behavior which means + * interface (SAP/P2P) function can keep operating on an unsafe channel with TX + * power derived by the driver based on regulatory/SAR during interface up. + * + * @QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK: + * u32 attribute, optional. Indicates all the interface types which are + * restricted for all frequency ranges provided in + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START and + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END. + * This attribute encapsulates bitmasks of interface types defined in + * enum nl80211_iftype. If an interface is marked as restricted the driver must + * move to a safe channel and if no safe channel is available the driver shall + * terminate that interface functionality. In absence of this attribute, + * interface (SAP/P2P) can still continue operating on an unsafe channel with + * TX power limit derived from either + * %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM or based on + * regulatory/SAE limits if %QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM + * is not provided. + */ +enum qca_wlan_vendor_attr_avoid_frequency_ext { + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_RANGE = 1, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_START = 2, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_END = 3, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_POWER_CAP_DBM = 4, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_IFACES_BITMASK = 5, + + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_MAX = + QCA_WLAN_VENDOR_ATTR_AVOID_FREQUENCY_AFTER_LAST - 1 +}; + +/* + * enum qca_wlan_vendor_attr_add_sta_node_params - Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE. + */ +enum qca_wlan_vendor_attr_add_sta_node_params { + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_INVALID = 0, + /* 6 byte MAC address of STA */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_MAC_ADDR = 1, + /* Authentication algorithm used by the station of size u16; + * defined in enum nl80211_auth_type. + */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_AUTH_ALGO = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_MAX = + QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST - 1 +}; + +/** + * enum qca_btc_chain_mode - Specifies BT coex chain mode. + * This enum defines the valid set of values of BT coex chain mode. + * These values are used by attribute %QCA_VENDOR_ATTR_BTC_CHAIN_MODE of + * %QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_BTC_CHAIN_SHARED: chains of BT and WLAN 2.4G are shared. + * @QCA_BTC_CHAIN_SEPARATED: chains of BT and WLAN 2.4G are separated. + */ +enum qca_btc_chain_mode { + QCA_BTC_CHAIN_SHARED = 0, + QCA_BTC_CHAIN_SEPARATED = 1, +}; + +/** + * enum qca_vendor_attr_btc_chain_mode - Specifies attributes for BT coex + * chain mode. + * Attributes for data used by QCA_NL80211_VENDOR_SUBCMD_BTC_CHAIN_MODE. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE: u32 attribute. + * Indicates the BT coex chain mode, are 32-bit values from + * enum qca_btc_chain_mode. This attribute is mandatory. + * + * @QCA_VENDOR_ATTR_COEX_BTC_CHAIN_MODE_RESTART: flag attribute. + * If set, vdev should be restarted when BT coex chain mode is updated. + * This attribute is optional. + */ +enum qca_vendor_attr_btc_chain_mode { + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_INVALID = 0, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE = 1, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_RESTART = 2, + + /* Keep last */ + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST, + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_MAX = + QCA_VENDOR_ATTR_BTC_CHAIN_MODE_LAST - 1, +}; + +/** + * enum qca_vendor_wlan_sta_flags - Station feature flags + * Bits will be set to 1 if the corresponding features are enabled. + * @QCA_VENDOR_WLAN_STA_FLAG_AMPDU: AMPDU is enabled for the station + * @QCA_VENDOR_WLAN_STA_FLAG_TX_STBC: TX Space-time block coding is enabled + for the station + * @QCA_VENDOR_WLAN_STA_FLAG_RX_STBC: RX Space-time block coding is enabled + for the station + */ +enum qca_vendor_wlan_sta_flags { + QCA_VENDOR_WLAN_STA_FLAG_AMPDU = BIT(0), + QCA_VENDOR_WLAN_STA_FLAG_TX_STBC = BIT(1), + QCA_VENDOR_WLAN_STA_FLAG_RX_STBC = BIT(2), +}; + +/** + * enum qca_vendor_wlan_sta_guard_interval - Station guard interval + * @QCA_VENDOR_WLAN_STA_GI_800_NS: Legacy normal guard interval + * @QCA_VENDOR_WLAN_STA_GI_400_NS: Legacy short guard interval + * @QCA_VENDOR_WLAN_STA_GI_1600_NS: Guard interval used by HE + * @QCA_VENDOR_WLAN_STA_GI_3200_NS: Guard interval used by HE + */ +enum qca_vendor_wlan_sta_guard_interval { + QCA_VENDOR_WLAN_STA_GI_800_NS = 0, + QCA_VENDOR_WLAN_STA_GI_400_NS = 1, + QCA_VENDOR_WLAN_STA_GI_1600_NS = 2, + QCA_VENDOR_WLAN_STA_GI_3200_NS = 3, +}; + +/** + * enum qca_wlan_vendor_attr_get_sta_info - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC: + * Required attribute in request for AP mode only, 6-byte MAC address, + * corresponding to the station's MAC address for which information is + * requested. For STA mode this is not required as the info always correspond + * to the self STA and the current/last association. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS: + * Optionally used in response, u32 attribute, contains a bitmap of different + * fields defined in enum qca_vendor_wlan_sta_flags, used in AP mode only. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL: + * Optionally used in response, u32 attribute, possible values are defined in + * enum qca_vendor_wlan_sta_guard_interval, used in AP mode only. + * Guard interval used by the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames received from station with retry + * bit set to 1 in FC. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter for number of data frames with broadcast or multicast address in + * the destination address received from the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED: + * Optionally used in response, u32 attribute, used in both STA and AP modes. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets and for which the TX status has been updated + * back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA and AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet and for which the TX status has been + * updated back to host from target. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL: + * Optionally used in response, u32 attribute, used in AP mode only. + * Counter in the target for the number of data frames successfully transmitted + * to the station. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY: + * Optionally used in response, u32 attribute, used in AP mode only. + * Value indicates the number of data frames successfully transmitted only + * after retrying the packets. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED: + * Optionally used in response, u32 attribute, used in both STA & AP mode. + * Value indicates the number of data frames not transmitted successfully even + * after retrying the packets for the number of times equal to the total number + * of retries allowed for that packet. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT: u32, used in + * the STA mode only. Represent the number of probe requests sent by the STA + * while attempting to roam on missing certain number of beacons from the + * connected AP. If queried in the disconnected state, this represents the + * count for the last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT: u32, used in + * the STA mode. Represent the number of probe responses received by the station + * while attempting to roam on missing certain number of beacons from the + * connected AP. When queried in the disconnected state, this represents the + * count when in last connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT: u32, used in the + * STA mode only. Represents the total number of frames sent out by STA + * including Data, ACK, RTS, CTS, Control Management. This data is maintained + * only for the connect session. Represents the count of last connected session, + * when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT: u32, used in the STA mode. + * Total number of RTS sent out by the STA. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT: u32, used in the + * STA mode.Represent the number of RTS transmission failure that reach retry + * limit. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT: u32, used in + * the STA mode. Represent the total number of non aggregated frames transmitted + * by the STA. This data is maintained per connect session. Represents the count + * of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT: u32, used in the + * STA mode. Represent the total number of aggregated frames transmitted by the + * STA. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT: u32, used in + * the STA mode. Represents the number of received frames with a good PLCP. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT: u32, + * used in the STA mode. Represents the number of occasions that no valid + * delimiter is detected by A-MPDU parser. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT: u32, used in the + * STA mode. Represents the number of frames for which CRC check failed in the + * MAC. This data is maintained per connect session. Represents the count of + * last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT: u32, used in the + * STA mode. Represents the number of unicast ACKs received with good FCS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT: u32, used in the STA + * mode. Represents the number of received Block Acks. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT: u32, used in the STA + * mode. Represents the number of beacons received from the connected BSS. This + * data is maintained per connect session. Represents the count of last + * connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT: u32, used in the + * STA mode. Represents the number of beacons received by the other BSS when in + * connected state (through the probes done by the STA). This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT: u64, used in + * the STA mode. Represents the number of received DATA frames with good FCS and + * matching Receiver Address when in connected state. This data is maintained + * per connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT: u32, used in the + * STA mode. Represents the number of RX Data multicast frames dropped by the HW + * when in the connected state. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS: u32, used in the + * STA mode. This represents the target power in dBm for the transmissions done + * to the AP in 2.4 GHz at 1 Mbps (DSSS) rate. This data is maintained per + * connect session. Represents the count of last connected session, when + * queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 2.4 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS: u32, used in the + * STA mode. This represents the Target power in dBm for transmissions done to + * the AP in 5 GHz at 6 Mbps (OFDM) rate. This data is maintained per connect + * session. Represents the count of last connected session, when queried in + * the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0: u32, used in the + * STA mode. This represents the Target power in dBm for for transmissions done + * to the AP in 5 GHz at MCS0 rate. This data is maintained per connect session. + * Represents the count of last connected session, when queried in the + * disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT: u32, used + * in the STA mode. This represents the Nested attribute representing the + * overflow counts of each receive buffer allocated to the hardware during the + * STA's connection. The number of hw buffers might vary for each WLAN + * solution and hence this attribute represents the nested array of all such + * HW buffer count. This data is maintained per connect session. Represents + * the count of last connected session, when queried in the disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER: u32, Max TX power (dBm) + * allowed as per the regulatory requirements for the current or last connected + * session. Used in the STA mode. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER: u32, Latest TX power + * (dBm) used by the station in its latest unicast frame while communicating + * to the AP in the connected state. When queried in the disconnected state, + * this represents the TX power used by the STA with last AP communication + * when in connected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL: u32, Adaptive noise immunity + * level used to adjust the RX sensitivity. Represents the current ANI level + * when queried in the connected state. When queried in the disconnected + * state, this corresponds to the latest ANI level at the instance of + * disconnection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_IES: Binary attribute containing + * the raw information elements from Beacon frames. Represents the Beacon frames + * of the current BSS in the connected state. When queried in the disconnected + * state, these IEs correspond to the last connected BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PROBE_RESP_IES: Binary attribute + * containing the raw information elements from Probe Response frames. + * Represents the Probe Response frames of the current BSS in the connected + * state. When queried in the disconnected state, these IEs correspond to the + * last connected BSSID. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_DRIVER_DISCONNECT_REASON: u32, Driver + * disconnect reason for the last disconnection if the disconnection is + * triggered from the host driver. The values are referred from + * enum qca_disconnect_reason_codes. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with an invalid MIC or a missing MME when PMF is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT: u32, used in STA mode + * only. This represents the number of group addressed robust management frames + * received from this station with the packet number less than or equal to the + * last received packet number when PMF is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT: u32, used in STA + * mode only. This represents the number of Beacon frames received from this + * station with an invalid MIC or a missing MME when beacon protection is + * enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT: u32, used in STA mode + * only. This represents number of Beacon frames received from this station with + * the packet number less than or equal to the last received packet number when + * beacon protection is enabled. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE: u32, used in + * STA mode only. The driver uses this attribute to populate the connection + * failure reason codes and the values are defined in + * enum qca_sta_connect_fail_reason_codes. Userspace applications can send + * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO vendor command after receiving + * a connection failure indication from the driver. The driver shall not + * include this attribute in response to the + * QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO command if there is no connection + * failure observed in the last attempted connection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE: u32, latest TX rate (Kbps) + * used by the station in its last TX frame while communicating to the AP in the + * connected state. When queried in the disconnected state, this represents the + * rate used by the STA in the last TX frame to the AP when it was connected. + * This attribute is used for STA mode only. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX: u32, used in STA mode only. + * This represents the rate index used by the STA for the last TX frame to the + * AP. When queried in the disconnected state, this gives the last RIX used by + * the STA in the last TX frame to the AP when it was connected. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT: u32, used in STA + * mode only. This represents the number of times the STA TSF goes out of sync + * from the AP after the connection. If queried in the disconnected state, this + * gives the count of TSF out of sync for the last connection. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON: u32, used in STA + * mode only. This represents the roam trigger reason for the last roaming + * attempted by the firmware. This can be queried either in connected state or + * disconnected state. Each bit of this attribute represents the different + * roam trigger reason code which are defined in enum qca_vendor_roam_triggers. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON: u32, used in STA mode + * only. This represents the roam fail reason for the last failed roaming + * attempt by the firmware. Different roam failure reason codes are specified + * in enum qca_vendor_roam_fail_reasons. This can be queried either in + * connected state or disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON: u32, used in + * STA mode only. This represents the roam invoke fail reason for the last + * failed roam invoke. Different roam invoke failure reason codes + * are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be + * queried either in connected state or disconnected state. + * + * @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only. + * This represents the average congestion duration of uplink frames in MAC + * queue in unit of ms. This can be queried either in connected state or + * disconnected state. + */ +enum qca_wlan_vendor_attr_get_sta_info { + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC = 1, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_FLAGS = 2, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_GUARD_INTERVAL = 3, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT = 4, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED = 6, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED = 7, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL = 8, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY = 9, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED = 10, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_PROBE_REQ_BMISS_COUNT = 11, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_PROBE_RESP_BMISS_COUNT = 12, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_ALL_COUNT = 13, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_COUNT = 14, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RTS_RETRY_FAIL_COUNT = 15, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_NON_AGGREGATED_COUNT = 16, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_DATA_AGGREGATED_COUNT = 17, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_GOOD_PLCP_COUNT = 18, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_INVALID_DELIMITER_COUNT = 19, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_FRAMES_CRC_FAIL_COUNT = 20, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_ACKS_GOOD_FCS_COUNT = 21, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BLOCKACK_COUNT = 22, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BEACON_COUNT = 23, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_OTHER_BEACON_COUNT = 24, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_UCAST_DATA_GOOD_FCS_COUNT = 25, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_DATA_BC_MC_DROP_COUNT = 26, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS = 27, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS = 28, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_MCS0 = 29, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS = 30, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_MCS0 = 31, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_HW_BUFFERS_OVERFLOW_COUNT = 32, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX_TX_POWER = 33, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER = 34, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL = 35, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_IES = 36, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_PROBE_RESP_IES = 37, + QCA_WLAN_VENDOR_ATTR_GET_STA_DRIVER_DISCONNECT_REASON = 38, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_MIC_ERROR_COUNT = 39, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BIP_REPLAY_COUNT = 40, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT = 41, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT = 42, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE = 43, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE = 44, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX = 45, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT = 46, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_update_sta_info - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_CONNECT_CHANNELS: Type is NLA_UNSPEC. + * Used in STA mode. This attribute represents the list of channel center + * frequencies in MHz (u32) the station has learnt during the last connection + * or roaming attempt. This information shall not signify the channels for + * an explicit scan request from the user space. Host drivers can update this + * information to the user space in both connected and disconnected state. + * In the disconnected state this information shall signify the channels + * scanned in the last connection/roam attempt that lead to the disconnection. + */ +enum qca_wlan_vendor_attr_update_sta_info { + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_CONNECT_CHANNELS = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_UPDATE_STA_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_disconnect_reason_codes - Specifies driver disconnect reason codes. + * Used when the driver triggers the STA to disconnect from the AP. + * + * @QCA_DISCONNECT_REASON_UNSPECIFIED: The host driver triggered the + * disconnection with the AP due to unspecified reasons. + * + * @QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE: The host driver triggered the + * disconnection with the AP due to a roaming failure. This roaming is triggered + * internally (host driver/firmware). + * + * @QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE: The driver disconnected from + * the AP when the user/external triggered roaming fails. + * + * @QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE: This reason code is used + * by the host driver whenever gateway reachability failure is detected and the + * driver disconnects with AP. + * + * @QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA: The driver disconnected from + * the AP on a channel switch announcement from it with an unsupported channel. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR: On a concurrent AP start + * with indoor channels disabled and if the STA is connected on one of these + * disabled channels, the host driver disconnected the STA with this reason + * code. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED: Disconnection due to an + * explicit request from the user to disable the current operating channel. + * + * @QCA_DISCONNECT_REASON_DEVICE_RECOVERY: STA disconnected from the AP due to + * the internal host driver/firmware recovery. + * + * @QCA_DISCONNECT_REASON_KEY_TIMEOUT: The driver triggered the disconnection on + * a timeout for the key installations from the user space. + * + * @QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE: The dDriver disconnected the + * STA on a band change request from the user space to a different band from the + * current operation channel/band. + * + * @QCA_DISCONNECT_REASON_IFACE_DOWN: The STA disconnected from the AP on an + * interface down trigger from the user space. + * + * @QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL: The host driver disconnected the + * STA on getting continuous transmission failures for multiple Data frames. + * + * @QCA_DISCONNECT_REASON_PEER_INACTIVITY: The STA does a keep alive + * notification to the AP by transmitting NULL/G-ARP frames. This disconnection + * represents inactivity from AP on such transmissions. + + * @QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT: This reason code is used on + * disconnection when SA Query times out (AP does not respond to SA Query). + * + * @QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE: The host driver disconnected the + * STA on missing the beacons continuously from the AP. + * + * @QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE: Disconnection due to STA not + * able to move to the channel mentioned by the AP in CSA. + * + * @QCA_DISCONNECT_REASON_USER_TRIGGERED: User triggered disconnection. + */ +enum qca_disconnect_reason_codes { + QCA_DISCONNECT_REASON_UNSPECIFIED = 0, + QCA_DISCONNECT_REASON_INTERNAL_ROAM_FAILURE = 1, + QCA_DISCONNECT_REASON_EXTERNAL_ROAM_FAILURE = 2, + QCA_DISCONNECT_REASON_GATEWAY_REACHABILITY_FAILURE = 3, + QCA_DISCONNECT_REASON_UNSUPPORTED_CHANNEL_CSA = 4, + QCA_DISCONNECT_REASON_OPER_CHANNEL_DISABLED_INDOOR = 5, + QCA_DISCONNECT_REASON_OPER_CHANNEL_USER_DISABLED = 6, + QCA_DISCONNECT_REASON_DEVICE_RECOVERY = 7, + QCA_DISCONNECT_REASON_KEY_TIMEOUT = 8, + QCA_DISCONNECT_REASON_OPER_CHANNEL_BAND_CHANGE = 9, + QCA_DISCONNECT_REASON_IFACE_DOWN = 10, + QCA_DISCONNECT_REASON_PEER_XRETRY_FAIL = 11, + QCA_DISCONNECT_REASON_PEER_INACTIVITY = 12, + QCA_DISCONNECT_REASON_SA_QUERY_TIMEOUT = 13, + QCA_DISCONNECT_REASON_BEACON_MISS_FAILURE = 14, + QCA_DISCONNECT_REASON_CHANNEL_SWITCH_FAILURE = 15, + QCA_DISCONNECT_REASON_USER_TRIGGERED = 16, +}; + +/** + * enum qca_wlan_vendor_attr_driver_disconnect_reason - Defines attributes + * used by %QCA_NL80211_VENDOR_SUBCMD_DRIVER_DISCONNECT_REASON vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASCON_CODE: u32 attribute. + * This attribute represents the driver specific reason codes (local + * driver/firmware initiated reasons for disconnection) defined + * in enum qca_disconnect_reason_codes. + */ +enum qca_wlan_vendor_attr_driver_disconnect_reason { + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASCON_CODE = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_MAX = + QCA_WLAN_VENDOR_ATTR_DRIVER_DISCONNECT_REASON_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_tspec_operation - Operation of the config TSPEC request + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION. + */ +enum qca_wlan_tspec_operation { + QCA_WLAN_TSPEC_ADD = 0, + QCA_WLAN_TSPEC_DEL = 1, + QCA_WLAN_TSPEC_GET = 2, +}; + +/** + * enum qca_wlan_tspec_direction - Direction in TSPEC + * As what is defined in IEEE Std 802.11-2016, Table 9-139. + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION. + */ +enum qca_wlan_tspec_direction { + QCA_WLAN_TSPEC_DIRECTION_UPLINK = 0, + QCA_WLAN_TSPEC_DIRECTION_DOWNLINK = 1, + QCA_WLAN_TSPEC_DIRECTION_DIRECT = 2, + QCA_WLAN_TSPEC_DIRECTION_BOTH = 3, +}; + +/** + * enum qca_wlan_tspec_ack_policy - MAC acknowledgement policy in TSPEC + * As what is defined in IEEE Std 802.11-2016, Table 9-141. + * + * Values for %QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY. + */ +enum qca_wlan_tspec_ack_policy { + QCA_WLAN_TSPEC_NORMAL_ACK = 0, + QCA_WLAN_TSPEC_NO_ACK = 1, + /* Reserved */ + QCA_WLAN_TSPEC_BLOCK_ACK = 3, +}; + +/** + * enum qca_wlan_vendor_attr_config_tspec - Defines attributes + * used by %QCA_NL80211_VENDOR_SUBCMD_CONFIG_TSPEC vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION: + * u8 attribute. Specify the TSPEC operation of this request. Possible values + * are defined in enum qca_wlan_tspec_operation. + * Mandatory attribute for all kinds of config TSPEC requests. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_TSID: + * u8 attribute. TS ID. Possible values are 0-7. + * Applicable for operation: QCA_WLAN_TSPEC_ADD, QCA_WLAN_TSPEC_DEL, + * QCA_WLAN_TSPEC_GET. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION: + * u8 attribute. Direction of data carried by the TS. Possible values are + * defined in enum qca_wlan_tspec_direction. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_APSD: + * Flag attribute. Indicate whether APSD is enabled for the traffic associated + * with the TS. set - enabled, not set - disabled. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_USER_PRIORITY: + * u8 attribute. User priority to be used for the transport of MSDUs/A-MSDUs + * belonging to this TS. Possible values are 0-7. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY: + * u8 attribute. Indicate whether MAC acknowledgements are required for + * MPDUs/A-MSDUs belonging to this TS and the form of those acknowledgements. + * Possible values are defined in enum qca_wlan_tspec_ack_policy. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_NOMINAL_MSDU_SIZE: + * u16 attribute. Specify the nominal size in bytes of MSDUs/A-MSDUs + * belonging to this TS. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAXIMUM_MSDU_SIZE: + * u16 attribute. Specify the maximum size in bytes of MSDUs/A-MSDUs + * belonging to this TS. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MIN_SERVICE_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds between the + * start of two successive SPs. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX_SERVICE_INTERVAL: + * u32 attribute. Specify the maximum interval in microseconds between the + * start of two successive SPs. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INACTIVITY_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds that can elapse + * without arrival or transfer of an MPDU belonging to the TS before this TS + * is deleted by the MAC entity at the HC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SUSPENSION_INTERVAL: + * u32 attribute. Specify the minimum interval in microseconds that can elapse + * without arrival or transfer of an MSDU belonging to the TS before the + * generation of successive QoS(+)CF-Poll is stopped for this TS. A value of + * 0xFFFFFFFF disables the suspension interval. The value of the suspension + * interval is always less than or equal to the inactivity interval. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_DATA_RATE: + * u32 attribute. Indicate the lowest data rate in bps specified at the MAC + * SAP for transport of MSDUs or A-MSDUs belonging to this TS within the + * bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MEAN_DATA_RATE: + * u32 attribute. Indicate the average data rate in bps specified at the MAC + * SAP for transport of MSDUs or A-MSDUs belonging to this TS within the + * bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_PEAK_DATA_RATE: + * u32 attribute. Indicate the maximum allowable data rate in bps specified at + * the MAC SAP for transport of MSDUs or A-MSDUs belonging to this TS within + * the bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_BURST_SIZE: + * u32 attribute. Specify the maximum burst size in bytes of the MSDUs/A-MSDUs + * belonging to this TS that arrive at the MAC SAP at the peak data rate. A + * value of 0 indicates that there are no bursts. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_PHY_RATE: + * u32 attribute. Indicate the minimum PHY rate in bps for transport of + * MSDUs/A-MSDUs belonging to this TS within the bounds of this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. An optional attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SURPLUS_BANDWIDTH_ALLOWANCE: + * u16 attribute. Specify the excess allocation of time (and bandwidth) over + * and above the stated application rates required to transport an MSDU/A-MSDU + * belonging to the TS in this TSPEC. + * Applicable for operation: QCA_WLAN_TSPEC_ADD. A mandatory attribute. + */ +enum qca_wlan_vendor_attr_config_tspec { + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_OPERATION = 1, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_TSID = 2, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_DIRECTION = 3, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_APSD = 4, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_USER_PRIORITY = 5, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_ACK_POLICY = 6, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_NOMINAL_MSDU_SIZE = 7, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAXIMUM_MSDU_SIZE = 8, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MIN_SERVICE_INTERVAL = 9, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX_SERVICE_INTERVAL = 10, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_INACTIVITY_INTERVAL = 11, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SUSPENSION_INTERVAL = 12, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_DATA_RATE = 13, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MEAN_DATA_RATE = 14, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_PEAK_DATA_RATE = 15, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_BURST_SIZE = 16, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MINIMUM_PHY_RATE = 17, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_SURPLUS_BANDWIDTH_ALLOWANCE = 18, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_MAX = + QCA_WLAN_VENDOR_ATTR_CONFIG_TSPEC_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_oci_override_frame_type - OCI override frame type + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ: SA Query Request frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP: SA Query Response frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ: FT Reassociation Request + * frame + * @QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FILS_REASSOC_REQ: FILS Reassociation + * Request frame. + */ +enum qca_wlan_vendor_oci_override_frame_type { + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ = 1, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP = 2, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ = 3, + QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FILS_REASSOC_REQ = 4, +}; + +/** + * enum qca_wlan_vendor_attr_oci_override: Represents attributes for + * OCI override request. These attributes are used inside nested attribute + * %QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE in QCA vendor command + * %QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION. + * + * @QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE: Required attribute, u8. + * Values from enum qca_wlan_vendor_oci_override_frame_type used in this + * attribute to specify the frame type in which the OCI is to be overridden. + * + * @QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY: Required (u32) + * OCI frequency (in MHz) to override in the specified frame type. + */ +enum qca_wlan_vendor_attr_oci_override { + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY = 2, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_MAX = + QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_medium_assess_type - Type of medium assess request + * + * Values for %QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE. + */ +enum qca_wlan_medium_assess_type { + QCA_WLAN_MEDIUM_ASSESS_CCA = 0, + QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT = 1, +}; + +/** + * enum qca_wlan_vendor_attr_medium_assess - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE: + * u8 attribute. Mandatory in all kinds of medium assess requests/responses. + * Specify the type of medium assess request and indicate its type in response. + * Possible values are defined in enum qca_wlan_medium_assess_type. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_PERIOD: + * u32 attribute. Mandatory in CCA request. + * Specify the assessment period in terms of seconds. Assessment result will be + * sent as the response to the CCA request after the assessment period. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TOTAL_CYCLE_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Total timer tick count of the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IDLE_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of idle time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IBSS_RX_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of Intra BSS traffic RX time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_OBSS_RX_COUNT: + * u32 attribute. Mandatory in response to CCA request. + * Timer tick count of Overlapping BSS traffic RX time in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX_IBSS_RSSI: + * s32 attribute. Mandatory in response to CCA request. + * Maximum RSSI of Intra BSS traffic in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MIN_IBSS_RSSI: + * s32 attribute. Mandatory in response to CCA request. + * Minimum RSSI of Intra BSS traffic in the assessment cycle. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE: + * u8 attribute. Mandatory in congestion report request. + * 1-enable 0-disable. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD: + * u8 attribute. Mandatory in congestion report enable request and will be + * ignored if present in congestion report disable request. Possible values are + * 0-100. A vendor event QCA_NL80211_VENDOR_SUBCMD_MEDIUM_ASSESS with the type + * QCA_WLAN_MEDIUM_ASSESS_CONGESTION_REPORT will be sent to userspace if + * congestion percentage reaches the configured threshold. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL: + * u8 attribute. Optional in congestion report enable request and will be + * ignored if present in congestion report disable request. + * Specify the interval of congestion report event in terms of seconds. Possible + * values are 1-255. Default value 1 will be used if this attribute is omitted + * or using invalid values. + * + * @QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_PERCENTAGE: + * u8 attribute. Mandatory in congestion report event. + * Indicate the actual congestion percentage. Possible values are 0-100. + */ +enum qca_wlan_vendor_attr_medium_assess { + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TYPE = 1, + + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_PERIOD = 2, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_TOTAL_CYCLE_COUNT = 3, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IDLE_COUNT = 4, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_IBSS_RX_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_OBSS_RX_COUNT = 6, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX_IBSS_RSSI = 7, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MIN_IBSS_RSSI = 8, + + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_ENABLE = 9, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_THRESHOLD = 10, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_REPORT_INTERVAL = 11, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_CONGESTION_PERCENTAGE = 12, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_MAX = + QCA_WLAN_VENDOR_ATTR_MEDIUM_ASSESS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mbssid_tx_vdev_status - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL: + * u8 attribute. Notify the TX VDEV status. Possible values 0, 1 + * belonging to MBSSID/EMA_AP configuration. 0 means Non-Tx VDEV, + * 1 means Tx VDEV. Mandatory attribute for all MBSSID VDEV status events. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT: + * u8 attribute, required. 1 means Tx VDEV up event. 0 means Tx VDEV down event. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID: + * u8 attribute, required. Indicates group id of Tx VDEV. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO: + * Nested attribute. This attribute shall be used by the driver to send + * group information. The attributes defined in enum + * qca_wlan_vendor_attr_mbssid_tx_vdev_group_info + * are nested in this attribute. + */ +enum qca_wlan_vendor_attr_mbssid_tx_vdev_status { + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_VAL = 1, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_EVENT = 2, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_ID = 3, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_MAX = + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_STATUS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info - Attributes used + * inside %QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO nested attribute. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX: + * u32 attribute, required. Contains interface index. + * + * @QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS: + * u8 attribute, required. 0 - means vdev is in down state. + * 1 - means vdev is in up state. + */ +enum qca_wlan_vendor_attr_mbssid_tx_vdev_group_info { + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_IF_INDEX = 1, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_STATUS = 2, + + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_MBSSID_TX_VDEV_GROUP_INFO - 1, +}; + +/** + * enum qca_wlan_concurrent_sta_policy_config - Concurrent STA policies + * + * @QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY: Preference to the primary + * STA interface has to be given while selecting the connection policies + * (e.g., BSSID, band, TX/RX chains, etc.) for the subsequent STA interface. + * An interface is set as primary through the attribute + * QCA_WLAN_VENDOR_ATTR_CONFIG_CONCURRENT_STA_PRIMARY. This policy is not + * applicable if the primary interface has not been set earlier. + * + * The intention is not to downgrade the primary STA performance, such as: + * - Do not reduce the number of TX/RX chains of primary connection. + * - Do not optimize DBS vs. MCC/SCC, if DBS ends up reducing the number of + * chains. + * - If using MCC, should set the MCC duty cycle of the primary connection to + * be higher than the secondary connection. + * + * @QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED: The connection policies for the + * subsequent STA connection shall be chosen to balance with the existing + * concurrent STA's performance. + * Such as + * - Can choose MCC or DBS mode depending on the MCC efficiency and hardware + * capability. + * - If using MCC, set the MCC duty cycle of the primary connection to be equal + * to the secondary. + * - Prefer BSSID candidates which will help provide the best "overall" + * performance for all the STA connections. + */ +enum qca_wlan_concurrent_sta_policy_config { + QCA_WLAN_CONCURRENT_STA_POLICY_PREFER_PRIMARY = 0, + QCA_WLAN_CONCURRENT_STA_POLICY_UNBIASED = 1, +}; + +/** + * enum qca_wlan_vendor_attr_concurrent_sta_policy - Defines attributes + * used by QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG: + * u8 attribute. Configures the concurrent STA policy configuration. + * Possible values are defined in enum qca_wlan_concurrent_sta_policy_config. + */ +enum qca_wlan_vendor_attr_concurrent_sta_policy { + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_CONFIG = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_MAX = + QCA_WLAN_VENDOR_ATTR_CONCURRENT_STA_POLICY_AFTER_LAST - 1, + +}; + +/** + * enum qca_sta_connect_fail_reason_codes - Defines values carried + * by QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_CONNECT_FAIL_REASON_CODE vendor + * attribute. + * @QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: No Probe Response frame received + * for unicast Probe Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: STA failed to send auth request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: AP didn't send ACK for + * auth request. + * @QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: Auth response is not + * received from AP. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: STA failed to send + * Association Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: AP didn't send ACK for + * Association Request frame. + * @QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: Association Response + * frame is not received from AP. + */ +enum qca_sta_connect_fail_reason_codes { + QCA_STA_CONNECT_FAIL_REASON_NO_BSS_FOUND = 1, + QCA_STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL = 2, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED = 3, + QCA_STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED = 4, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL = 5, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED = 6, + QCA_STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED = 7, +}; + +/** + * enum qca_wlan_vendor_usable_channels_filter - Bitmask of different + * filters defined in this enum are used in attribute + * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK. + * + * @QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX: When this bit is set, the driver + * shall filter the channels which are not usable because of coexistence with + * cellular radio. + * @QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY: When this bit is set, the driver + * shall filter the channels which are not usable because of existing active + * interfaces in the driver and will result in Multi Channel Concurrency, etc. + * + */ +enum qca_wlan_vendor_usable_channels_filter { + QCA_WLAN_VENDOR_FILTER_CELLULAR_COEX = 0, + QCA_WLAN_VENDOR_FILTER_WLAN_CONCURRENCY = 1, +}; + +/** + * enum qca_wlan_vendor_attr_chan_info - Attributes used inside + * %QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO nested attribute. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ: + * u32 attribute, required. Indicates the center frequency of the primary + * channel in MHz. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ: + * u32 attribute. Indicates the center frequency of the primary segment of the + * channel in MHz. This attribute is required when reporting 40 MHz, 80 MHz, + * 160 MHz, and 320 MHz channels. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ: + * u32 attribute. Indicates the center frequency of the secondary segment of + * 80+80 channel in MHz. This attribute is required only when + * QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH is set to NL80211_CHAN_WIDTH_80P80. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH: + * u32 attribute, required. Indicates the bandwidth of the channel, possible + * values are defined in enum nl80211_chan_width. + * + * @QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK: + * u32 attribute, required. Indicates all the interface types for which this + * channel is usable. This attribute encapsulates bitmasks of interface types + * defined in enum nl80211_iftype. + * + */ +enum qca_wlan_vendor_attr_chan_info { + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_PRIMARY_FREQ = 1, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG0_FREQ = 2, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_SEG1_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_BANDWIDTH = 4, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_IFACE_MODE_MASK = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_CHAN_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_usable_channels - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK: + * u32 attribute. Indicates the bands from which the channels should be reported + * in response. This attribute encapsulates bit masks of bands defined in enum + * nl80211_band. Optional attribute, if not present in the request the driver + * shall return channels from all supported bands. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK: + * u32 attribute. Indicates all the interface types for which the usable + * channels information is requested. This attribute encapsulates bitmasks of + * interface types defined in enum nl80211_iftype. Optional attribute, if not + * present in the request the driver shall send information of all supported + * interface modes. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK: + * u32 attribute. This attribute carries information of all filters that shall + * be applied while populating usable channels information by the driver. This + * attribute carries bit masks of different filters defined in enum + * qca_wlan_vendor_usable_channels_filter. Optional attribute, if not present + * in the request the driver shall send information of channels without applying + * any of the filters that can be configured through this attribute. + * + * @QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO: + * Nested attribute. This attribute shall be used by the driver to send + * usability information of each channel. The attributes defined in enum + * qca_wlan_vendor_attr_chan_info are used inside this attribute. + */ +enum qca_wlan_vendor_attr_usable_channels { + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_BAND_MASK = 1, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_IFACE_MODE_MASK = 2, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_FILTER_MASK = 3, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_CHAN_INFO = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_MAX = + QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_radar_history: Used by the vendor command + * QCA_NL80211_VENDOR_SUBCMD_GET_RADAR_HISTORY to get DFS radar history. + * + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES: Nested attribute to carry + * the list of radar history entries. + * Each entry contains freq, timestamp, and radar signal detect flag. + * The driver shall add an entry when CAC has finished, or radar signal + * has been detected post AP beaconing. The driver shall maintain at least + * 8 entries in order to save CAC result for a 160 MHz channel. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ: u32 attribute. + * Channel frequency in MHz. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP: u64 nanoseconds. + * CLOCK_BOOTTIME timestamp when this entry is updated due to CAC + * or radar detection. + * @QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED: NLA_FLAG attribute. + * This flag indicates radar signal has been detected. + */ +enum qca_wlan_vendor_attr_radar_history { + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_INVALID = 0, + + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_ENTRIES = 1, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_FREQ = 2, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_TIMESTAMP = 3, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_DETECTED = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST, + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_MAX = + QCA_WLAN_VENDOR_ATTR_RADAR_HISTORY_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_mcc_quota_type: MCC channel time quota type + * + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR: In the event, it indicates that the + * target exited MCC state and cleared the quota information. In the + * command it clears MCC quota setting and restores adaptive scheduling. + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED: Channel time quota is fixed and + * will not be changed. + * @QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC: Channel time quota is dynamic + * and the target may change the quota based on the data activity. + */ +enum qca_wlan_vendor_mcc_quota_type { + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_CLEAR = 0, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_FIXED = 1, + QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_DYNAMIC = 2, +}; + +/** + * enum qca_wlan_vendor_attr_mcc_quota: Used by the vendor event + * QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA to indicate MCC channel + * quota information or as a command to set the required MCC quota for an + * interface. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE: u32 attribute. + * The type is defined in enum qca_wlan_vendor_mcc_quota_type. + * In a command this specifies the MCC quota type to be set for the interface. + * In an event this provides the current quota type in force. + * This is required in a command and an event. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES: Nested attribute to carry + * the list of channel quota entries. + * In an event each entry contains the frequency and respective time quota for + * all the MCC interfaces. + * In a command it specifies the interface index and respective time quota. + * In a command only one entry (ifindex, quota pair) may be specified. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ: u32 attribute. + * Channel frequency in MHz. This is present only in an event. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE: u32 attribute. + * Channel time quota expressed as percentage. + * This is present in an event and a command. + * In an command, the user shall specify the quota to be allocated for the + * interface represented by %QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX. + * In an event this provides the existing quota for the channel. + * + * @QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX: u32 attribute. + * Specifies the interface index (netdev) for which the corresponding + * configurations are applied. This is required in a command only. Only one + * interface index may be specified. If not specified, the configuration is + * rejected. + */ +enum qca_wlan_vendor_attr_mcc_quota { + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_ENTRIES = 2, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_CHAN_TIME_PERCENTAGE = 4, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_IFINDEX = 5, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST, + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_MAX = + QCA_WLAN_VENDOR_ATTR_MCC_QUOTA_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_mdns_offload - Attributes used by + * %QCA_NL80211_VENDOR_SUBCMD_MDNS_OFFLOAD vendor command. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE: Required (flag) + * Enable mDNS offload. This attribute is mandatory to enable + * mDNS offload feature. If this attribute is not present, mDNS offload + * is disabled. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE: Nested attribute containing + * one or more %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY attributes. This + * attribute is mandatory when enabling the feature, and not required when + * disabling the feature. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY: Nested attribute containing + * the following attributes: + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT + * %QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN: Required string attribute. + * It consists of a hostname and ".local" as the domain name. The character + * set is limited to UTF-8 encoding. The maximum allowed size is 63 bytes. + * It is used to compare the domain in the "QU" query. Only 1 FQDN is + * supported per vdev. + * For example: myphone.local + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT: Required + * u16 attribute. It specifies the total number of resource records present + * in the answer section of the answer payload. This attribute is needed by the + * firmware to populate the mDNS response frame for mDNS queries without having + * to parse the answer payload. + * + * @QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD: Required binary blob + * attribute sent by the mdnsResponder from userspace. It contains resource + * records of various types (e.g., A, AAAA, PTR, TXT) and service list. This + * payload is passed down to the firmware and is transmitted in response to + * mDNS queries. + * The maximum supported size of the answer payload is 512 bytes. + */ +enum qca_wlan_vendor_attr_mdns_offload { + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENABLE = 1, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_TABLE = 2, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ENTRY = 3, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_FQDN = 4, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_RESOURCE_RECORDS_COUNT = 5, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_ANSWER_PAYLOAD = 6, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_MAX = + QCA_WLAN_VENDOR_ATTR_MDNS_OFFLOAD_AFTER_LAST - 1, +}; + +/** + * qca_wlan_vendor_monitor_data_frame_type - Represent the various + * Data frame types to be sent over the monitor interface. + */ +enum qca_wlan_vendor_monitor_data_frame_type { + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16), + QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17), +}; + +/** + * qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various + * Management frame types to be sent over the monitor interface. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the Management Frames. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the Management frames + * except the Beacon frame. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected + * BSSID Beacon frames. Valid only in the connected state. + * @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents + * the Beacon frames obtained during the scan (off channel and connected + * channel), when in connected state. + */ +enum qca_wlan_vendor_monitor_mgmt_frame_type { + QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_MGMT_NO_BEACON = BIT(1), + QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2), + QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3), +}; + +/** + * qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various + * Control frame types to be sent over the monitor interface. + * @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the Control frames + * @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger frame + */ +enum qca_wlan_vendor_monitor_ctrl_frame_type { + QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0), + /* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set + */ + QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1), +}; + +/** + * enum qca_wlan_vendor_attr_set_monitor_mode - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the + * monitor mode. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Data frame types to be monitored (u32). These Data frames + * are represented by enum qca_wlan_vendor_monitor_data_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Data frame types to be monitored (u32). These Data frames + * are represented by enum qca_wlan_vendor_monitor_data_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Management frame types to be monitored (u32). These + * Management frames are represented by + * enum qca_wlan_vendor_monitor_mgmt_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Management frame types to be monitored (u32). These + * Management frames are represented by + * enum qca_wlan_vendor_monitor_mgmt_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute. + * Represents the TX Control frame types to be monitored (u32). These Control + * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute. + * Represents the RX Control frame types to be monitored (u32). These Control + * frames are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type. + * + * @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL: u32 + * attribute. + * Represents the interval in milliseconds only for the connected Beacon frames, + * expecting the connected BSS's Beacon frames to be sent on the monitor + * interface at this specific interval. + */ +enum qca_wlan_vendor_attr_set_monitor_mode { + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX = + QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_roam_scan_state - Roam scan state flags. + * Bits will be set to 1 if the corresponding state is enabled. + * + * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start. + * @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end. + */ +enum qca_wlan_vendor_roam_scan_state { + QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0), + QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1), +}; + +/** + * enum qca_wlan_vendor_roam_event_type - Roam event type flags. + * Bits will be set to 1 if the corresponding event is notified. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event + * carries the trigger reason. When set, it is expected that the roam event + * carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries + * the BSSID, RSSI, frequency info of the AP to which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event + * carries the roam fail reason. When set, it is expected that the roam event + * carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the + * BSSID, RSSI, frequency info of the AP to which the roam was attempted. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam + * event carries the roam invoke fail reason. When set, it is expected that + * the roam event carries the respective reason via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON. + * + * @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event + * carries the roam scan state. When set, it is expected that the roam event + * carries the respective scan state via the attribute + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding + * frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST. + */ +enum qca_wlan_vendor_roam_event_type { + QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0), + QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1), + QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2), + QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3), +}; + +/** + * enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info. + * Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address + * representing the BSSID of the AP to which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value + * in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is + * attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, frequency in MHz + * on which the roam is attempted. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in + * STA mode only. This represents the roam fail reason for the last failed + * roaming attempt by the firmware for the specific BSSID. Different roam + * failure reason codes are specified in enum qca_vendor_roam_fail_reasons. + */ +enum qca_wlan_vendor_attr_roam_events_candidate_info { + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_roam_events - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the + * roam events to the driver or notify these events from the driver. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the + * driver/firmware to enable/disable the notification of roam events. It's a + * mandatory attribute and used only in the request from the userspace to the + * host driver. 1-Enable, 0-Disable. + * If the roaming is totally offloaded to the firmware, this request when + * enabled shall mandate the firmware to notify all the relevant roam events + * represented by the below attributes. If the host is in the suspend mode, + * the behavior of the firmware to notify these events is guided by + * QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get + * these events in the suspend state, the firmware is expected to wake up the + * host before the respective events are notified. Please note that such a + * request to get the events in the suspend state will have a definite power + * implication. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents + * that the roam events need to be notified in the suspend state too. By + * default, these roam events are notified in the resume state. With this flag, + * the roam events are notified in both resume and suspend states. + * This attribute is used in the request from the userspace to the host driver. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only. + * Represents the different roam event types, signified by the enum + * qca_wlan_vendor_roam_event_type. + * Each bit of this attribute represents the different roam even types reported + * through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA + * mode only. This represents the roam trigger reason for the last roaming + * attempted by the firmware. Each bit of this attribute represents the + * different roam trigger reason code which are defined in enum + * qca_vendor_roam_triggers. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in + * STA mode only. This represents the roam invoke fail reason for the last + * failed roam invoke. Different roam invoke failure reason codes + * are specified in enum qca_vendor_roam_invoke_fail_reasons. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info + * for which the roam is attempted. Each entry is a nested attribute defined + * by enum qca_wlan_vendor_attr_roam_events_candidate_info. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents + * the scan state on which the roam events need to be notified. The values for + * this attribute are referred from enum qca_wlan_vendor_roam_scan_state. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + * + * @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of + * u32 values. List of frequencies in MHz considered for a roam scan. + * This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS. + */ +enum qca_wlan_vendor_attr_roam_events { + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX = + QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST -1, +}; + +/** + * enum qca_wlan_ratemask_params_type - Rate mask config type + * + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM: CCK/OFDM rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HT: HT rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT: VHT rate mask config + * @QCA_WLAN_RATEMASK_PARAMS_TYPE_HE: HE rate mask config + */ +enum qca_wlan_ratemask_params_type { + QCA_WLAN_RATEMASK_PARAMS_TYPE_CCK_OFDM = 0, + QCA_WLAN_RATEMASK_PARAMS_TYPE_HT = 1, + QCA_WLAN_RATEMASK_PARAMS_TYPE_VHT = 2, + QCA_WLAN_RATEMASK_PARAMS_TYPE_HE = 3, +}; + +/** + * enum qca_wlan_vendor_attr_ratemask_params - Used by the + * vendor command QCA_NL80211_VENDOR_SUBCMD_RATEMASK_CONFIG. + * This is used to set the rate mask value to be used in rate selection. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST: + * Array of nested containing attributes + * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE and + * QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE: u8, represents + * the different PHY types to which the rate mask config is to be applied. + * The values for this attribute are referred from enum + * qca_wlan_vendor_ratemask_params_type. + * + * @QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP: binary, rate mask bitmap. + * A bit value of 1 represents rate is enabled and a value of 0 + * represents rate is disabled. + * For HE targets, 12 bits correspond to one NSS setting. + * b0-13 => NSS1, MCS 0-13 + * b14-27 => NSS2, MCS 0-13 and so on for other NSS. + * For VHT targets, 10 bits correspond to one NSS setting. + * b0-9 => NSS1, MCS 0-9 + * b10-19 => NSS2, MCS 0-9 and so on for other NSS. + * For HT targets, 8 bits correspond to one NSS setting. + * b0-7 => NSS1, MCS 0-7 + * b8-15 => NSS2, MCS 0-7 and so on for other NSS. + * For OFDM/CCK targets, 8 bits correspond to one NSS setting. + */ +enum qca_wlan_vendor_attr_ratemask_params { + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_LIST = 1, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_TYPE = 2, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_BITMAP = 3, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_MAX = + QCA_WLAN_VENDOR_ATTR_RATEMASK_PARAMS_AFTER_LAST - 1, +}; + +#endif /* QCA_VENDOR_H */ diff --git a/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h b/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h new file mode 100644 index 0000000..054d840 --- /dev/null +++ b/wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2020, The Linux Foundation. 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 The Linux Foundation 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 "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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. + */ + +#ifndef WPA_DRIVER_COMMON_LIB +#define WPA_DRIVER_COMMON_LIB + +#include "android_drv.h" +#define OUI_LEN 3 +#define MAX_CMD_LEN 32 +#define MAC_ADDR_LEN 6 +#define COUNTRY_LEN 4 + +#define IEEE80211_HE_OPERATION_VHT_OPER_MASK 0x00004000 +#define IEEE80211_HE_OPERATION_CO_LOC_BSS_MASK 0x00008000 +#define IEEE80211_HE_OPERATION_6G_OPER_MASK 0x00020000 + +#define HE_OPER_VHT_CH_WIDTH_OFFSET 0 +#define HE_OPER_VHT_CENTER_FRQ_SEG0_OFFSET 1 +#define HE_OPER_VHT_CENTER_FRQ_SEG1_OFFSET 2 +#define HE_OPER_VHT_MAX_OFFSET 2 + +#define HE_OPER_CO_LOCATED_MAX_OFFSET 0 + +#define HE_OPER_6G_PARAMS_OFFSET 1 + +#define HE_OPER_6G_PARAMS_SUB_CH_BW_MASK 0X03 + +#define CHANNEL_BW_INVALID 255 + +/* Define short names */ +#define GET_STATION_INFO_AKM \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM +#define GET_STATION_INFO_HT_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION +#define GET_STATION_INFO_VHT_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION +#define GET_STATION_INFO_REMOTE_LAST_RX_RATE \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE +#define GET_STATION_INFO_REMOTE_SUPPORTED_MODE \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE +#define GET_STATION_INFO_REMOTE_CH_WIDTH \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH +#define GET_STATION_INFO_REMOTE_RX_RETRY_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT +#define GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT +#define GET_STATION_INFO_BEACON_IES \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES +#define GET_STATION_INFO_DRIVER_DISCONNECT_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON +#define GET_STATION_INFO_ASSOC_REQ_IES \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES +#define GET_STATION_INFO_HE_OPERATION \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION +#define GET_STATION_INFO_MAX \ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX + +#define GET_STA_INFO_MAC \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAC +#define GET_STA_INFO_RX_RETRY_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_RETRY_COUNT +#define GET_STA_INFO_RX_BC_MC_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_RX_BC_MC_COUNT +#define GET_STA_INFO_TX_RETRY_SUCCEED \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_SUCCEED +#define GET_STA_INFO_TX_RETRY_EXHAUSTED \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TX_RETRY_EXHAUSTED +#define GET_STA_INFO_TARGET_TX_TOTAL \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_TOTAL +#define GET_STA_INFO_TARGET_TX_RETRY \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY +#define GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_TX_RETRY_EXHAUSTED +#define GET_STA_INFO_ANI_LEVEL \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ANI_LEVEL +#define GET_STA_INFO_LATEST_TX_RATE \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_RATE +#define GET_STA_INFO_LATEST_RIX \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_RIX +#define GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TSF_OUT_OF_SYNC_COUNT +#define GET_STA_INFO_LATEST_TX_POWER \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_LATEST_TX_POWER +#define GET_STA_INFO_ROAM_TRIGGER_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON +#define GET_STA_INFO_TARGET_POWER_24G_1MBPS \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_1MBPS +#define GET_STA_INFO_TARGET_POWER_24G_6MBPS \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_24G_6MBPS +#define GET_STA_INFO_TARGET_POWER_5G_6MBPS \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_TARGET_POWER_5G_6MBPS +#define GET_STA_INFO_ROAM_FAIL_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON +#define GET_STA_INFO_ROAM_INVOKE_FAIL_REASON \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON +#define GET_STA_INFO_MAX \ + QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + +struct bss_info { + uint8_t oui[OUI_LEN]; + char ssid[MAX_SSID_LEN + 1]; + int channel; + int bw; + int rssi; + int data_rate; + /* 0 : 11b, 1 : 11g, 2 : 11n, 3 : 11a, 4 : 11ac */ + int mode_80211; + /* 0 : SISO, 1 : MIMO (2X2), 2 : MIMO (3X3), 3 : MIMO (4X4) */ + int snr; + int noise; + int akm; + int roaming_count; + /* 0: None, 1: 11k, 2: 11v, 3: 11kv */ + int mode_11kv; + /* Bit mask value of 11kv support */ + int mask_11kv; + u32 disc_reasn_code; + u32 ani_level; + u32 roam_trigger_reason; + u32 roam_fail_reason; + u32 roam_invoke_fail_reason; + u32 tsf_out_of_sync_count; + u32 latest_tx_power; + u32 latest_tx_rate; + u32 target_power_24g_1mbps; + u32 target_power_24g_6mbps; + u32 target_power_5g_6mbps; +}; + +enum get_info_cmd { + GETSTATSBSSINFO = 1, + SETCELLSWITCHMODE = 2, + GET_DRIVER_SUPPORTED_FEATURES = 3, +}; + +struct resp_info { + u32 subcmd; + char *reply_buf; + int reply_buf_len; + enum get_info_cmd cmd_type; + uint8_t mac_addr[MAC_ADDR_LEN]; + u32 freq; + uint8_t country[COUNTRY_LEN]; +}; + +#define QCA_NL80211_VENDOR_SUBCMD_GET_STATION 121 + +#ifndef CHANWIDTH_USE_HT +#define CHANWIDTH_USE_HT VHT_CHANWIDTH_USE_HT +#endif /* CHANWIDTH_USE_HT */ +#ifndef CHANWIDTH_80MHZ +#define CHANWIDTH_80MHZ VHT_CHANWIDTH_80MHZ +#endif /* CHANWIDTH_80MHZ */ +#ifndef CHANWIDTH_160MHZ +#define CHANWIDTH_160MHZ VHT_CHANWIDTH_160MHZ +#endif /* CHANWIDTH_160MHZ */ +#ifndef CHANWIDTH_80P80MHZ +#define CHANWIDTH_80P80MHZ VHT_CHANWIDTH_80P80MHZ +#endif /* CHANWIDTH_80P80MHZ */ + +/* HE channel widths */ + +#define HE_CHANWIDTH_20MHZ 0 +#define HE_CHANWIDTH_40MHZ 1 +#define HE_CHANWIDTH_80MHZ 2 +#define HE_CHANWIDTH_160MHZ 3 + +/** + * enum qca_wlan_vendor_attr_get_station - Sub commands used by + * QCA_NL80211_VENDOR_SUBCMD_GET_STATION to get the corresponding + * station information. The information obtained through these + * commands signify the current info in connected state and + * latest cached information during the connected state , if queried + * when in disconnected state. + */ +enum qca_wlan_vendor_attr_get_station { + QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO, + QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON, + QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STATION_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_station_info - Station Info queried + * through QCA_NL80211_VENDOR_SUBCMD_GET_STATION. + */ +enum qca_wlan_vendor_attr_get_station_info { + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_INVALID = 0, + /* + * Get the standard NL attributes Nested with this attribute. + * Ex : Query BW , BITRATE32 , NSS , Signal , Noise of the Link - + * NL80211_ATTR_SSID / NL80211_ATTR_SURVEY_INFO (Connected Channel) / + * NL80211_ATTR_STA_INFO + */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_LINK_INFO_ATTR, + /* + * Get the standard NL attributes Nested with this attribute. + * Ex : Query HT/VHT Capability advertized by the AP. + * NL80211_ATTR_VHT_CAPABILITY / NL80211_ATTR_HT_CAPABILITY + */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_AP_INFO_ATTR, + + /* Number of successful Roam attempts before a disconnect, + * Unsigned 32 bit value + */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ROAM_COUNT, + + /* Authentication Key Management Type used for the connected session. + * Signified by enum qca_wlan_auth_type + */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AKM, + + /* 802.11 Mode of the connected Session, + * signified by enum qca_wlan_802_11_mode + */ + QCA_WLAN_VENDOR_ATTR_802_11_MODE, + + /* HS20 Indication Element */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_AP_INFO_HS20_INDICATION, + + /* HT/VHT operation elements */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HT_OPERATION, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_VHT_OPERATION, + + /* Status Code Corresponding to the Association Failure. + * Unsigned 32 bit value + */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSSOC_FAIL_REASON, + + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_MAX_PHY_RATE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_PACKETS, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_BYTES, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_PACKETS, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BYTES, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_TX_RATE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_LAST_RX_RATE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_WMM, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SUPPORTED_MODE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AMPDU, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_STBC, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_STBC, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_CH_WIDTH, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_SGI_ENABLE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_PAD, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_RETRY_COUNT, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_BC_MC_COUNT, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_FAILURE, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_AVG_RSSI_PER_CHAIN, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_SUCCEED, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_RX_LAST_PKT_RSSI, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_TOTAL_FW, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_FW, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_REMOTE_TX_RETRY_EXHAUST_FW, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_BEACON_IES, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_DRIVER_DISCONNECT_REASON, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_HE_OPERATION, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_MAX = + QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_AFTER_LAST - 1, +}; + +#define NOISE_FLOOR_DBM (96) + +#define WMI_MAX_CHAINS (3) + +enum qca_vendor_wlan_chan_width { + QCA_VENDOR_WLAN_CHAN_WIDTH_20 = 0, + QCA_VENDOR_WLAN_CHAN_WIDTH_40 = 1, + QCA_VENDOR_WLAN_CHAN_WIDTH_80 = 2, + QCA_VENDOR_WLAN_CHAN_WIDTH_80_80 = 3, + QCA_VENDOR_WLAN_CHAN_WIDTH_160 = 4, +}; + +enum qca_vendor_wlan_802_11_mode { + QCA_VENDOR_WLAN_802_11_MODE_B = 0, + QCA_VENDOR_WLAN_802_11_MODE_G = 1, + QCA_VENDOR_WLAN_802_11_MODE_N = 2, + QCA_VENDOR_WLAN_802_11_MODE_A = 3, + QCA_VENDOR_WLAN_802_11_MODE_AC = 4, + QCA_VENDOR_WLAN_802_11_MODE_AX = 5, +}; + +enum qca_vendor_wlan_phy_mode { + QCA_VENDOR_WLAN_PHY_MODE_LEGACY = 0, + QCA_VENDOR_WLAN_PHY_MODE_HT = 1, + QCA_VENDOR_WLAN_PHY_MODE_VHT = 2, + QCA_VENDOR_WLAN_PHY_MODE_HE = 3, +}; + +struct assoc_req_ie_flags { + u8 ht_supported:1; + u8 vht_supported:1; + u8 he_supported:1; +}; + +struct remote_sta_info { + u8 num_sta; + u8 num_request_vendor_sta_info; + u8 num_received_vendor_sta_info; + u8 num_request_nl80211_sta_info; + u8 num_received_nl80211_sta_info; + u8 mac_addr[MAC_ADDR_LEN]; + u32 rx_retry_pkts; + u32 rx_bcmc_pkts; + u16 cap; + u32 freq; + u8 bandwidth; + s8 rssi; + u32 data_rate; + u32 dot11_mode; + u32 reason; + u8 supported_mode; + u32 tx_pckts; + u32 tx_failures; + u32 tx_rate; + s32 avg_rssi_per_chain[WMI_MAX_CHAINS]; + u32 tx_pkts_retried; + u32 tx_pkts_retry_exhausted; + s32 rx_lastpkt_rssi; + u32 tx_pkts_total; + u32 tx_pkts_retries; + u32 tx_pkts_fw_total; + u32 tx_pkts_fw_retries; + u32 tx_pkts_fw_retry_exhausted; + u32 ani_level; + u32 roam_trigger_reason; + u32 roam_fail_reason; + u32 roam_invoke_fail_reason; + u32 tsf_out_of_sync_count; + u32 latest_tx_power; + u32 latest_tx_rate; + u32 latest_rix; + u32 target_power_24g_1mbps; + u32 target_power_24g_6mbps; + u32 target_power_5g_6mbps; + u8 *supp_op_classes; /* Supported Operating Classes element, if + * received, starting from the Length field */ + u8 *supp_channels; + u32 supported_band; + bool show_band; + struct assoc_req_ie_flags flags; + uint8_t country[COUNTRY_LEN]; +}; + +#endif diff --git a/wcn6740/wcnss-service/Android.mk b/wcn6740/wcnss-service/Android.mk new file mode 100644 index 0000000..ab866a3 --- /dev/null +++ b/wcn6740/wcnss-service/Android.mk @@ -0,0 +1,28 @@ +ifneq (,$(filter arm aarch64 arm64, $(TARGET_ARCH))) +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED),true) +LOCAL_VENDOR_MODULE := true +endif +LOCAL_MODULE := wcnss_service +LOCAL_HEADER_LIBRARIES += vendor_common_inc +LOCAL_SRC_FILES := wcnss_service.c +LOCAL_SHARED_LIBRARIES := libc libcutils libutils liblog +ifeq ($(strip $(TARGET_USES_QCOM_WCNSS_QMI)),true) +LOCAL_CFLAGS += -DWCNSS_QMI +ifeq ($(filter 10% Q% q%,$(TARGET_PLATFORM_VERSION)),) +#For Android R and above, assuming not compiling on Q and lower +LOCAL_HEADER_LIBRARIES += libqmi_common_headers +else +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qmi-framework/inc +endif +LOCAL_SRC_FILES += wcnss_qmi_client.c +LOCAL_SHARED_LIBRARIES += libqmiservices libqmi_cci +LOCAL_HEADER_LIBRARIES += libmdmdetect_headers +LOCAL_SHARED_LIBRARIES += libmdmdetect +LOCAL_HEADER_LIBRARIES += libril-qc-qmi-services-headers +endif #TARGET_USES_QCOM_WCNSS_QMI +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS += -Wall -Werror +include $(BUILD_EXECUTABLE) +endif diff --git a/wcn6740/wcnss-service/wcnss_qmi_client.c b/wcn6740/wcnss-service/wcnss_qmi_client.c new file mode 100644 index 0000000..3e1fb0e --- /dev/null +++ b/wcn6740/wcnss-service/wcnss_qmi_client.c @@ -0,0 +1,135 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. +--------------------------------------------------------------------------*/ + +#ifdef WCNSS_QMI +#define LOG_TAG "wcnss_qmi" +#include <cutils/log.h> +#include "wcnss_qmi_client.h" +#include "qmi_client.h" +#include "device_management_service_v01.h" +#include <cutils/properties.h> +#include <string.h> + +#define SUCCESS 0 +#define FAILED -1 + +#define WLAN_ADDR_SIZE 6 +#define DMS_QMI_TIMEOUT (2000) + +static qmi_client_type dms_qmi_client; +static int dms_init_done = FAILED; + +int wcnss_init_qmi() +{ + qmi_client_error_type qmi_client_err; + + ALOGE("%s: Initialize wcnss QMI Interface", __func__); + qmi_client_os_params dms_os_params; + + memset(&dms_os_params, 0, sizeof(qmi_client_os_params)); + qmi_client_err = qmi_client_init_instance(dms_get_service_object_v01(), + QMI_CLIENT_INSTANCE_ANY, NULL, NULL, + &dms_os_params, 5000, &dms_qmi_client); + + if (qmi_client_err != QMI_NO_ERR){ + ALOGE("%s: Error while Initializing QMI Client: %d", + __func__, qmi_client_err); + goto exit; + } + + dms_init_done = SUCCESS; + return SUCCESS; + +exit: + return FAILED; +} + +int wcnss_qmi_get_wlan_address(unsigned char *pBdAddr) +{ + qmi_client_error_type qmi_client_err; + dms_get_mac_address_req_msg_v01 addr_req; + dms_get_mac_address_resp_msg_v01 addr_resp; + + if ((dms_init_done == FAILED) || (pBdAddr == NULL)) { + ALOGE("%s: DMS init fail or pBdAddr is NULL", __func__); + return FAILED; + } + + /* clear the request content */ + memset(&addr_req, 0, sizeof(addr_req)); + + /*Request to get the WLAN MAC address */ + addr_req.device = DMS_DEVICE_MAC_WLAN_V01; + + qmi_client_err = qmi_client_send_msg_sync(dms_qmi_client, + QMI_DMS_GET_MAC_ADDRESS_REQ_V01, &addr_req, sizeof(addr_req), + &addr_resp, sizeof(addr_resp), DMS_QMI_TIMEOUT); + + if (qmi_client_err != QMI_NO_ERR){ + ALOGE("%s: Failed to get Rsp from Modem Error:%d", + __func__, qmi_client_err); + return FAILED; + } + + ALOGE("%s: Mac Address_valid: %d Mac Address Len: %d", + __func__, addr_resp.mac_address_valid, + addr_resp.mac_address_len); + + if (addr_resp.mac_address_valid && + (addr_resp.mac_address_len == WLAN_ADDR_SIZE)) { + memcpy(pBdAddr, addr_resp.mac_address, + addr_resp.mac_address_len); + ALOGE("%s: Succesfully Read WLAN MAC Address", __func__); + return SUCCESS; + } else { + ALOGE("%s: Failed to Read WLAN MAC Address", __func__); + return FAILED; + } +} + +void wcnss_qmi_deinit() +{ + qmi_client_error_type qmi_client_err; + + ALOGE("%s: Deinitialize wcnss QMI Interface", __func__); + + if (dms_init_done == FAILED) { + ALOGE("%s: DMS Service was not Initialized", __func__); + return; + } + + qmi_client_err = qmi_client_release(dms_qmi_client); + + if (qmi_client_err != QMI_NO_ERR){ + ALOGE("%s: Error while releasing qmi_client: %d", + __func__, qmi_client_err); + } + + dms_init_done = FAILED; +} +#endif diff --git a/wcn6740/wcnss-service/wcnss_qmi_client.h b/wcn6740/wcnss-service/wcnss_qmi_client.h new file mode 100644 index 0000000..51fefac --- /dev/null +++ b/wcn6740/wcnss-service/wcnss_qmi_client.h @@ -0,0 +1,49 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. +--------------------------------------------------------------------------*/ +#if defined(__BIONIC_FORTIFY) +#include <sys/system_properties.h> +#endif + +#define MODEM_BASEBAND_PROPERTY "ro.baseband" +#if defined(__BIONIC_FORTIFY) +#define MODEM_BASEBAND_PROPERTY_SIZE PROP_VALUE_MAX +#else +#define MODEM_BASEBAND_PROPERTY_SIZE 10 +#endif +#define MODEM_BASEBAND_VALUE_APQ "apq" + +#ifdef WCNSS_QMI +#ifndef WCNSS_QMI_CLIENT_H +#define WCNSS_QMI_CLIENT_H + +int wcnss_init_qmi(void); +int wcnss_qmi_get_wlan_address(unsigned char *pBdAddr); +void wcnss_qmi_deinit(void); + +#endif +#endif diff --git a/wcn6740/wcnss-service/wcnss_service.c b/wcn6740/wcnss-service/wcnss_service.c new file mode 100644 index 0000000..c817be1 --- /dev/null +++ b/wcn6740/wcnss-service/wcnss_service.c @@ -0,0 +1,815 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. 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 The Linux Foundation 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 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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. +--------------------------------------------------------------------------*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <dirent.h> +#include <ctype.h> +#include <grp.h> +#include <utime.h> +#include <sys/stat.h> +#include <sys/sendfile.h> +#define LOG_TAG "wcnss_service" +#include <cutils/log.h> +#include <cutils/properties.h> +#ifdef WCNSS_QMI +#include "wcnss_qmi_client.h" +#include "mdm_detect.h" +#endif + +#define SUCCESS 0 +#define FAILED -1 +#define BYTE_0 0 +#define BYTE_1 8 +#define BYTE_2 16 +#define BYTE_3 24 +#define UNUSED(x) (void)(x) + +#define MAX_FILE_LENGTH (1024) +#define WCNSS_MAX_CMD_LEN (128) + +/* control messages to wcnss driver */ +#define WCNSS_USR_CTRL_MSG_START 0x00000000 +#define WCNSS_USR_SERIAL_NUM (WCNSS_USR_CTRL_MSG_START + 1) +#define WCNSS_USR_HAS_CAL_DATA (WCNSS_USR_CTRL_MSG_START + 2) +#define WCNSS_USR_WLAN_MAC_ADDR (WCNSS_USR_CTRL_MSG_START + 3) + + +#define WCNSS_CAL_CHUNK (3*1024) +#define WCNSS_CAL_FILE "/data/vendor/wifi/WCNSS_qcom_wlan_cal.bin" +#define WCNSS_FACT_FILE "/data/vendor/wifi/WCN_FACTORY" +#define WCNSS_DEVICE "/dev/wcnss_wlan" +#define WCNSS_CTRL "/dev/wcnss_ctrl" +#define WLAN_INI_FILE_DEST "/data/vendor/wifi/WCNSS_qcom_cfg.ini" +#define WLAN_INI_FILE_SOURCE "/vendor/etc/wifi/WCNSS_qcom_cfg.ini" +#define WCNSS_HAS_CAL_DATA\ + "/sys/module/wcnsscore/parameters/has_calibrated_data" +#define WLAN_DRIVER_ATH_DEFAULT_VAL "0" + +#define ASCII_A 65 +#define ASCII_a 97 +#define ASCII_0 48 +#define HEXA_A 10 +#define HEX_BASE 16 + +#ifdef WCNSS_QMI +#define WLAN_ADDR_SIZE 6 +unsigned char wlan_nv_mac_addr[WLAN_ADDR_SIZE]; +#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" + +/* As we Want to write in 00:0a:f5:11:22:33 format in sysfs file + so taking mac length as 12 char + 5 for ":" + NULL + */ +#define WLAN_MAC_ADDR_STRING 18 +#endif + +#define MAX_SOC_INFO_NAME_LEN (15) +#define MAX_DATA_NVBIN_PATH_LEN (64) +#define QRD_DYNAMIC_NV_PROP "persist.sys.dynamic.nv" +#define QRD_HW_PLATFORM "QRD" +#define QRD_PLATFORM_SUBTYPE_ID 0 +#define PERSIST_NVFILE "/persist/WCNSS_qcom_wlan_nv.bin" +#define DATA_NVFILE_DIR "/data/misc/wifi/nvbin/" +#define SYSFS_SOCID_PATH1 "/sys/devices/soc0/soc_id" +#define SYSFS_SOCID_PATH2 "/sys/devices/system/soc/soc0/id" +#define SYSFS_HW_PLATFORM_PATH1 "/sys/devices/soc0/hw_platform" +#define SYSFS_HW_PLATFORM_PATH2 "/sys/devices/system/soc/soc0/hw_platform" +#define SYSFS_PLATFORM_SUBTYPE_PATH1 "/sys/devices/soc0/platform_subtype_id" +#define SYSFS_PLATFORM_SUBTYPE_PATH2 "/sys/devices/system/soc/soc0/platform_subtype_id" +#define SYSFS_PLATFORM_VERSION_PATH1 "/sys/devices/soc0/platform_version" +#define SYSFS_PLATFORM_VERSION_PATH2 "/sys/devices/system/soc/soc0/platform_version" +#define SOCINFO_HWVER_MAJOR(ver) (((ver) & 0x00ff0000) >> 16) +#define SOCINFO_HWVER_MINOR(ver) ((ver) & 0x000000ff) +#define GET_SOC_INFO(buf, soc_node_path1, soc_node_path2, info_got) \ + { if (get_soc_info(buf, soc_node_path1, soc_node_path2) < 0) \ + { \ + ALOGE("get_soc_info failed!\n"); \ + return FAILED; \ + } \ + info_got = atoi(buf); \ + } + +int wcnss_write_cal_data(int fd_dev) +{ + int rcount = 0; + int size = 0; + int rc = 0; + int wcount = 0; + int fd_file; + struct stat st; + + char buf[WCNSS_CAL_CHUNK]; + + ALOGI("wcnss_write_cal_data trying to write cal"); + + rc = stat(WCNSS_CAL_FILE, &st); + if (rc < 0) { + ALOGE("Failed to stat cal file : %s", + strerror(errno)); + goto exit; + } + + size = st.st_size; + + fd_file = open(WCNSS_CAL_FILE, O_RDONLY); + if (fd_file < 0) { + ALOGE("cal file doesn't exist: %s", + strerror(errno)); + rc = fd_file; + goto exit; + } + + /* write the file size first, so that platform driver knows + * when it recieves the full data */ + wcount = write(fd_dev, (void *)&size, 4); + if (wcount != 4) { + ALOGE("Failed to write to wcnss device : %s", + strerror(errno)); + rc = wcount; + goto exit_close; + } + + do { + rcount = read(fd_file, (void *)buf, sizeof(buf)); + if (rcount < 0) { + ALOGE("Failed to read from cal file ; %s", + strerror(errno)); + rc = rcount; + goto exit_remove; + } + + if (!rcount) + break; + + wcount = write(fd_dev, buf, rcount); + if (wcount < 0) { + ALOGE("Failed to write to wcnss device : %s", + strerror(errno)); + rc = wcount; + goto exit_close; + } + + } while (rcount); + close(fd_file); + + return SUCCESS; + +exit_remove: + close(fd_file); + remove("WCNSS_CAL_FILE"); + return rc; + +exit_close: + close(fd_file); + +exit: + return rc; +} + + +int wcnss_read_and_store_cal_data(int fd_dev) +{ + int rcount = 0; + int wcount = 0; + int fd_file = -1; + int rc = 0; + + char buf[WCNSS_CAL_CHUNK]; + + ALOGI("wcnss_read_and_store_cal_data trying to read cal"); + + do { + /* wait on this read until data comes from fw */ + rcount = read(fd_dev, (void *)buf, sizeof(buf)); + if (rcount < 0) { + ALOGE("Failed to read from wcnss device : %s", + strerror(errno)); + rc = rcount; + goto exit; + } + + /* truncate the file only if there is fw data, this read + * may never return if the fw decides that no more cal is + * required; and the data we have now is good enough. + */ + if (fd_file < 0) { + fd_file = open(WCNSS_CAL_FILE, O_WRONLY + | O_CREAT | O_TRUNC, 0664); + if (fd_file < 0) { + ALOGE("Failed to open cal file : %s", + strerror(errno)); + rc = fd_file; + goto exit; + } + } + + if (!rcount) + break; + + wcount = write(fd_file, buf, rcount); + if (wcount < 0) { + ALOGE("Failed to write to cal file : %s", + strerror(errno)); + rc = wcount; + goto exit_remove; + } + + } while (rcount); + + close(fd_file); + + return SUCCESS; + +exit_remove: + close(fd_file); + remove(WCNSS_CAL_FILE); + +exit: + return rc; +} + + +void find_full_path(char *cur_dir, char *file_to_find, char *full_path) +{ + DIR *dir; + struct stat st; + struct dirent *dr; + char cwd[1024]; + int rc; + + chdir(cur_dir); + + dir = opendir("."); + + if (dir != NULL) { + while ((dr = readdir(dir))) { + + rc = lstat(dr->d_name, &st); + if (rc < 0) { + ALOGE("lstat failed %s", strerror(errno)); + return; + } + if (S_ISDIR(st.st_mode)) { + if ((strcmp(dr->d_name, ".")) && + (strcmp(dr->d_name, ".."))) { + find_full_path(dr->d_name, + file_to_find, full_path); + } + } else if (!strcmp(file_to_find, dr->d_name)) { + getcwd(cwd, sizeof(cwd)); + snprintf(full_path, MAX_FILE_LENGTH, "%s/%s", + cwd, file_to_find); + } + } + closedir(dir); + } + + chdir(".."); +} + +void setup_wlan_config_file() +{ + int rfd; + int wfd; + struct stat st_dest, st_src; + int rc_dest; + int rc; + struct group *grp; + struct utimbuf new_time; + + rc = stat(WLAN_INI_FILE_SOURCE, &st_src); + if (rc != 0) { + ALOGE("source file do not exist %s", WLAN_INI_FILE_SOURCE); + return; + } + + rc_dest = stat(WLAN_INI_FILE_DEST, &st_dest); + if (rc_dest == 0 && st_dest.st_size && + (st_dest.st_mtime > st_src.st_mtime)) { + ALOGE("wlan ini file exists %s and is newer than %s", + WLAN_INI_FILE_DEST, WLAN_INI_FILE_SOURCE); + goto out_nocopy; + } + + rfd = open(WLAN_INI_FILE_SOURCE, O_RDONLY); + if (rfd < 0) { + ALOGE("Failed to open ini source file: %s", strerror(errno)); + return; + } + + wfd = open(WLAN_INI_FILE_DEST, O_WRONLY | O_CREAT | O_TRUNC, 0660); + if (wfd < 0) { + ALOGE("Failed to open ini dest file: %s", strerror(errno)); + close(rfd); + return; + } + + rc = sendfile(wfd, rfd, 0, st_src.st_size); + if (rc != st_src.st_size) { + ALOGE("Failed to copy ini file: %s", strerror(errno)); + goto out; + } + + new_time.actime = st_src.st_atime; + new_time.modtime = st_src.st_mtime; + + rc = utime(WLAN_INI_FILE_DEST, &new_time); + if (rc != 0) + ALOGE("could not preserve the timestamp %s", strerror(errno)); + + grp = getgrnam("wifi"); + if (grp != NULL) { + rc = chown(WLAN_INI_FILE_DEST, -1, grp->gr_gid); + if (rc != 0) + ALOGE("Failed change group of ini file %s", strerror(errno)); + } else { + ALOGE("Failed to get group wifi %s", strerror(errno)); + } + + property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST); + +out: + close(rfd); + close(wfd); + return; + +out_nocopy: + property_set("vendor.wlan.driver.config", WLAN_INI_FILE_DEST); + return; +} +unsigned int convert_string_to_hex(char* string) +{ + int idx; + unsigned long int hex_num = 0; + for(idx = 0; string[idx] != '\0'; idx++){ + if(isalpha(string[idx])) { + if(string[idx] >='a' && string[idx] <='f') { + hex_num = hex_num * HEX_BASE + ((int)string[idx] + - ASCII_a + HEXA_A); + } else if ( string[idx] >='A' && string[idx] <='F') { + hex_num = hex_num * HEX_BASE + ((int)string[idx] + - ASCII_A + HEXA_A); + } else + hex_num = hex_num * HEX_BASE + (int)string[idx]; + } else { + hex_num = hex_num * HEX_BASE + (string[idx]- ASCII_0); + } + } + hex_num = hex_num & 0xFFFFFFFF; + return hex_num; +} + + +#ifdef WCNSS_QMI +void setup_wcnss_parameters(int *cal, int nv_mac_addr) +#else +void setup_wcnss_parameters(int *cal) +#endif +{ + char msg[WCNSS_MAX_CMD_LEN]; + char serial[PROPERTY_VALUE_MAX]; + int fd, rc, pos = 0; + struct stat st; + unsigned int serial_num = 0; + + fd = open(WCNSS_CTRL, O_WRONLY); + if (fd < 0) { + ALOGE("Failed to open %s : %s", WCNSS_CTRL, strerror(errno)); + return; + } + + rc = property_get("ro.serialno", serial, ""); + if (rc) { + serial_num = convert_string_to_hex(serial); + ALOGE("Serial Number is %x", serial_num); + + msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_1; + msg[pos++] = WCNSS_USR_SERIAL_NUM >> BYTE_0; + msg[pos++] = serial_num >> BYTE_3; + msg[pos++] = serial_num >> BYTE_2; + msg[pos++] = serial_num >> BYTE_1; + msg[pos++] = serial_num >> BYTE_0; + + if (write(fd, msg, pos) < 0) { + ALOGE("Failed to write to %s : %s", WCNSS_CTRL, + strerror(errno)); + goto fail; + } + } + +#ifdef WCNSS_QMI + if (SUCCESS == nv_mac_addr) + { + pos = 0; + msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_1; + msg[pos++] = WCNSS_USR_WLAN_MAC_ADDR >> BYTE_0; + msg[pos++] = wlan_nv_mac_addr[0]; + msg[pos++] = wlan_nv_mac_addr[1]; + msg[pos++] = wlan_nv_mac_addr[2]; + msg[pos++] = wlan_nv_mac_addr[3]; + msg[pos++] = wlan_nv_mac_addr[4]; + msg[pos++] = wlan_nv_mac_addr[5]; + + ALOGI("WLAN MAC Addr:" MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wlan_nv_mac_addr)); + + if (write(fd, msg, pos) < 0) { + ALOGE("Failed to write to %s : %s", WCNSS_CTRL, + strerror(errno)); + goto fail; + } + } +#endif + + pos = 0; + msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_1; + msg[pos++] = WCNSS_USR_HAS_CAL_DATA >> BYTE_0; + + rc = stat(WCNSS_FACT_FILE, &st); + if (rc == 0) { + ALOGE("Factory file found, deleting cal file"); + unlink(WCNSS_CAL_FILE); + goto fail_resp; + } + + rc = stat(WCNSS_CAL_FILE, &st); + if (rc != 0) { + ALOGE("CAL file not found"); + goto fail_resp; + } + + /* has cal data */ + msg[pos++] = 1; + + if (write(fd, msg, pos) < 0) { + ALOGE("Failed to write to %s : %s", WCNSS_CTRL, + strerror(errno)); + goto fail; + } + + ALOGI("Correctly triggered cal file"); + *cal = SUCCESS; + close(fd); + return; + +fail_resp: + msg[pos++] = 0; + if (write(fd, msg, pos) < 0) + ALOGE("Failed to write to %s : %s", WCNSS_CTRL, + strerror(errno)); + +fail: + *cal = FAILED; + close(fd); + return; +} + +void setup_wlan_driver_ath_prop() +{ + property_set("vendor.wlan.driver.ath", WLAN_DRIVER_ATH_DEFAULT_VAL); +} + +#ifdef WCNSS_QMI +int check_modem_compatability(struct dev_info *mdm_detect_info) +{ + char args[MODEM_BASEBAND_PROPERTY_SIZE] = {0}; + int ret = 0; + /* Get the hardware property */ + ret = property_get(MODEM_BASEBAND_PROPERTY, args, ""); + if (ret > MODEM_BASEBAND_PROPERTY_SIZE) { + ALOGE("property [%s] has size [%d] that exceeds max [%d]", + MODEM_BASEBAND_PROPERTY, ret, MODEM_BASEBAND_PROPERTY_SIZE); + return 0; + } + /* This will check for the type of hardware, and if the + hardware type needs external modem, it will check if the + modem type is external*/ + if(!strncmp(MODEM_BASEBAND_VALUE_APQ, args, 3)) { + + for (ret = 0; ret < mdm_detect_info->num_modems; ret++) { + if (mdm_detect_info->mdm_list[ret].type == MDM_TYPE_EXTERNAL) { + ALOGE("Hardware supports external modem"); + return 1; + } + } + ALOGE("Hardware does not support external modem"); + return 0; + } + return 1; +} +#endif + +static int read_line_from_file(const char *path, char *buf, size_t count) +{ + char * fgets_ret; + FILE * fd; + int rv; + + fd = fopen(path, "r"); + if (fd == NULL) + return -1; + + fgets_ret = fgets(buf, (int)count, fd); + if (NULL != fgets_ret) { + rv = (int)strlen(buf); + } else { + rv = ferror(fd); + } + + fclose(fd); + + return rv; +} + +static int get_soc_info(char *buf, char *soc_node_path1, + char *soc_node_path2) +{ + int ret = 0; + + ret = read_line_from_file(soc_node_path1, buf, + MAX_SOC_INFO_NAME_LEN); + if (ret < 0) { + ret = read_line_from_file(soc_node_path2, buf, + MAX_SOC_INFO_NAME_LEN); + if (ret < 0) { + ALOGE("getting socinfo(%s, %d) failed.\n", + soc_node_path1, ret); + return ret; + } + } + if (ret && buf[ret - 1] == '\n') + buf[ret - 1] = '\0'; + + return ret; +} + +static int get_data_nvfile_path(char *data_nvfile_path, + struct stat *pdata_nvfile_stat) +{ + char target_board_platform[PROP_VALUE_MAX] = {'\0'}; + char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'}; + int soc_id, platform_subtype_id, platform_version; + int major_hwver, minor_hwver; + int rc; + + rc = property_get("ro.board.platform", target_board_platform, ""); + if (!rc) + { + ALOGE("get ro.board.platform fail, rc=%d(%s)\n", + rc, strerror(errno)); + return FAILED; + } + + GET_SOC_INFO(buf, SYSFS_SOCID_PATH1, SYSFS_SOCID_PATH2, soc_id); + GET_SOC_INFO(buf, SYSFS_PLATFORM_SUBTYPE_PATH1, + SYSFS_PLATFORM_SUBTYPE_PATH2, platform_subtype_id); + GET_SOC_INFO(buf, SYSFS_PLATFORM_VERSION_PATH1, + SYSFS_PLATFORM_VERSION_PATH2, platform_version); + + major_hwver = SOCINFO_HWVER_MAJOR(platform_version); + minor_hwver = SOCINFO_HWVER_MINOR(platform_version); + + snprintf(data_nvfile_path, MAX_DATA_NVBIN_PATH_LEN, + "%s%s_%d_0x%02x_0x%02x_0x%02x_nv.bin", DATA_NVFILE_DIR, + target_board_platform, soc_id, platform_subtype_id&0xff, + major_hwver&0xff, minor_hwver&0xff); + ALOGI("data_nvfile_path %s\n", + data_nvfile_path); + + if (stat(data_nvfile_path, pdata_nvfile_stat) != 0) + { + ALOGE("source file do not exist %s\n", + data_nvfile_path); + return FAILED; + } + + return SUCCESS; +} + +static int nvbin_sendfile(const char *dst, const char *src, + struct stat *src_stat) +{ + struct utimbuf new_time; + int fp_src, fp_dst; + int rc; + if ((fp_src = open(src, O_RDONLY)) < 0) + { + ALOGE("open %s failed(%s).\n", + src, strerror(errno)); + return FAILED; + } + + if ((fp_dst = open(dst, O_WRONLY |O_TRUNC)) < 0) + { + close(fp_src); + ALOGE("open %s failed(%s).\n", + dst, strerror(errno)); + return FAILED; + } + + if (sendfile(fp_dst, fp_src, 0, src_stat->st_size) == -1) + { + ALOGE("dynamic nv sendfile failed: (%s).\n", + strerror(errno)); + rc = FAILED; + goto exit; + } + + new_time.actime = src_stat->st_atime; + new_time.modtime = src_stat->st_mtime; + if (utime(dst, &new_time) != 0) + { + ALOGE("could not preserve the timestamp %s", + strerror(errno)); + rc = FAILED; + goto exit; + } + + rc = SUCCESS; +exit: + close(fp_dst); + close(fp_src); + return rc; +} +void dynamic_nv_replace() +{ + char data_nvfile_path[MAX_DATA_NVBIN_PATH_LEN] = {'\0'}; + char property_nv_replaced_status [PROPERTY_VALUE_MAX] = { '\0' }; + char buf[MAX_SOC_INFO_NAME_LEN] = {'\0'}; + struct stat data_nvfile_stat; + int rc; + + if (property_get(QRD_DYNAMIC_NV_PROP, property_nv_replaced_status, NULL) + && strcmp(property_nv_replaced_status, "done") == 0) { + ALOGI("dynamic nv have been replaced. leave\n"); + return; + } + + rc = get_soc_info(buf, SYSFS_HW_PLATFORM_PATH1, SYSFS_HW_PLATFORM_PATH2); + if (rc < 0) + { + ALOGE("get_soc_info(HW_PLATFORM) fail!\n"); + return; + } else { + if( 0 != strncmp(buf, QRD_HW_PLATFORM, MAX_SOC_INFO_NAME_LEN)) + { + ALOGI("dynamic nv only for QRD platform, current platform:%s.\n", + buf); + return; + } + } + + rc = get_data_nvfile_path(data_nvfile_path, &data_nvfile_stat); + if (rc != SUCCESS) + { + ALOGE("Get source file path fail !\n"); + return; + } + + if (property_set(QRD_DYNAMIC_NV_PROP, "replacing") < 0) + { + ALOGE("set %s to replacing failed (%s).\n", + QRD_DYNAMIC_NV_PROP, strerror(errno)); + return; + } + + rc = nvbin_sendfile(PERSIST_NVFILE, data_nvfile_path, &data_nvfile_stat); + if ( rc != SUCCESS) + { + ALOGE("nvbin_sendfile failed.\n"); + return; + } + + if (property_set(QRD_DYNAMIC_NV_PROP, "done") < 0) + { + ALOGE("set %s to done failed(%s).\n", + QRD_DYNAMIC_NV_PROP, strerror(errno)); + return; + } + + ALOGI("dynamic nv replace sucessfully!\n"); + +} + +int main(int argc, char *argv[]) +{ + UNUSED(argc), UNUSED(argv); + int rc; + int fd_dev, ret_cal; +#ifdef WCNSS_QMI + int nv_mac_addr = FAILED; + struct dev_info mdm_detect_info; + int nom = 0; +#endif + + setup_wlan_config_file(); + +#ifdef WCNSS_QMI + /* Call ESOC API to get the number of modems. + If the number of modems is not zero, only then proceed + with the eap_proxy intialization.*/ + + nom = get_system_info(&mdm_detect_info); + + if (nom > 0) + ALOGE("Failed to get system info, ret %d", nom); + + if (mdm_detect_info.num_modems == 0) { + ALOGE("wcnss_service: No Modem support for this target" + " number of modems is %d", mdm_detect_info.num_modems); + goto nomodem; + } + + ALOGE("wcnss_service: num_modems = %d", mdm_detect_info.num_modems); + + if(!check_modem_compatability(&mdm_detect_info)) { + ALOGE("wcnss_service: Target does not have external modem"); + goto nomodem; + } + + /* initialize the DMS client and request the wlan mac address */ + + if (SUCCESS == wcnss_init_qmi()) { + + rc = wcnss_qmi_get_wlan_address(wlan_nv_mac_addr); + + if (rc == SUCCESS) { + nv_mac_addr = SUCCESS; + ALOGE("WLAN MAC Addr:" MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wlan_nv_mac_addr)); + } else + ALOGE("Failed to Get MAC addr from modem"); + + wcnss_qmi_deinit(); + } + else + ALOGE("Failed to Initialize wcnss QMI Interface"); + +nomodem: +#endif + + dynamic_nv_replace(); + +#ifdef WCNSS_QMI + setup_wcnss_parameters(&ret_cal, nv_mac_addr); +#else + setup_wcnss_parameters(&ret_cal); +#endif + + fd_dev = open(WCNSS_DEVICE, O_RDWR); + if (fd_dev < 0) { + ALOGE("Failed to open wcnss device : %s", + strerror(errno)); + return fd_dev; + } + + if (ret_cal != FAILED) { + rc = wcnss_write_cal_data(fd_dev); + if (rc != SUCCESS) + ALOGE("No cal data is written to WCNSS %d", rc); + else + ALOGE("Cal data is successfully written to WCNSS"); + } + + setup_wlan_driver_ath_prop(); + + rc = wcnss_read_and_store_cal_data(fd_dev); + if (rc != SUCCESS) + ALOGE("Failed to read and save cal data %d", rc); + else + ALOGI("Calibration data was successfull written to %s", + WCNSS_CAL_FILE); + + close(fd_dev); + + return rc; +} |