summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHsiu-Chang Chen <hsiuchangchen@google.com>2022-07-22 11:13:41 +0800
committerHsiu-Chang Chen <hsiuchangchen@google.com>2022-07-22 11:13:41 +0800
commiteb93a5121d88779e93a2b361ac0ddac1e98c02e8 (patch)
tree336c9598dab15a5e7e6e750e86cfaf0c60a6a766
parent79861d3fe23093fe704c1d341642b434fb323aa6 (diff)
downloadwlan-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
-rw-r--r--Android.mk6
-rw-r--r--legacy/Android.mk1
-rw-r--r--legacy/cld80211-lib/Android.mk (renamed from cld80211-lib/Android.mk)0
-rw-r--r--legacy/cld80211-lib/cld80211_lib.c (renamed from cld80211-lib/cld80211_lib.c)0
-rw-r--r--legacy/cld80211-lib/cld80211_lib.h (renamed from cld80211-lib/cld80211_lib.h)0
-rw-r--r--legacy/qcwcn/Android.mk (renamed from qcwcn/Android.mk)0
-rw-r--r--legacy/qcwcn/config/Android.mk (renamed from qcwcn/config/Android.mk)0
-rw-r--r--legacy/qcwcn/wcnss-service/Android.mk (renamed from qcwcn/wcnss-service/Android.mk)0
-rw-r--r--legacy/qcwcn/wcnss-service/wcnss_qmi_client.c (renamed from qcwcn/wcnss-service/wcnss_qmi_client.c)0
-rw-r--r--legacy/qcwcn/wcnss-service/wcnss_qmi_client.h (renamed from qcwcn/wcnss-service/wcnss_qmi_client.h)0
-rw-r--r--legacy/qcwcn/wcnss-service/wcnss_service.c (renamed from qcwcn/wcnss-service/wcnss_service.c)0
-rw-r--r--legacy/qcwcn/wifi_hal/Android.mk (renamed from qcwcn/wifi_hal/Android.mk)0
-rw-r--r--legacy/qcwcn/wifi_hal/common.cpp (renamed from qcwcn/wifi_hal/common.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/common.h (renamed from qcwcn/wifi_hal/common.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/cpp_bindings.cpp (renamed from qcwcn/wifi_hal/cpp_bindings.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/cpp_bindings.h (renamed from qcwcn/wifi_hal/cpp_bindings.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/gscan.cpp (renamed from qcwcn/wifi_hal/gscan.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/gscan_event_handler.cpp (renamed from qcwcn/wifi_hal/gscan_event_handler.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/gscan_event_handler.h (renamed from qcwcn/wifi_hal/gscan_event_handler.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/gscancommand.h (renamed from qcwcn/wifi_hal/gscancommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/ifaceeventhandler.cpp (renamed from qcwcn/wifi_hal/ifaceeventhandler.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/ifaceeventhandler.h (renamed from qcwcn/wifi_hal/ifaceeventhandler.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/list.cpp (renamed from qcwcn/wifi_hal/list.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/list.h (renamed from qcwcn/wifi_hal/list.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/llstats.cpp (renamed from qcwcn/wifi_hal/llstats.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/llstatscommand.h (renamed from qcwcn/wifi_hal/llstatscommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan.cpp (renamed from qcwcn/wifi_hal/nan.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan_cert.h (renamed from qcwcn/wifi_hal/nan_cert.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan_i.h (renamed from qcwcn/wifi_hal/nan_i.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan_ind.cpp (renamed from qcwcn/wifi_hal/nan_ind.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan_req.cpp (renamed from qcwcn/wifi_hal/nan_req.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/nan_rsp.cpp (renamed from qcwcn/wifi_hal/nan_rsp.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/nancommand.h (renamed from qcwcn/wifi_hal/nancommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/pkt_stats.h (renamed from qcwcn/wifi_hal/pkt_stats.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/qca-vendor_copy.h (renamed from qcwcn/wifi_hal/qca-vendor_copy.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/radio_mode.cpp (renamed from qcwcn/wifi_hal/radio_mode.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/radio_mode.h (renamed from qcwcn/wifi_hal/radio_mode.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/rb_wrapper.cpp (renamed from qcwcn/wifi_hal/rb_wrapper.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/rb_wrapper.h (renamed from qcwcn/wifi_hal/rb_wrapper.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/ring_buffer.cpp (renamed from qcwcn/wifi_hal/ring_buffer.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/ring_buffer.h (renamed from qcwcn/wifi_hal/ring_buffer.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/roam.cpp (renamed from qcwcn/wifi_hal/roam.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/roamcommand.h (renamed from qcwcn/wifi_hal/roamcommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/rssi_monitor.cpp (renamed from qcwcn/wifi_hal/rssi_monitor.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/rssi_monitor.h (renamed from qcwcn/wifi_hal/rssi_monitor.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/rtt.cpp (renamed from qcwcn/wifi_hal/rtt.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/sync.h (renamed from qcwcn/wifi_hal/sync.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/tdls.cpp (renamed from qcwcn/wifi_hal/tdls.cpp)0
-rwxr-xr-xlegacy/qcwcn/wifi_hal/tdlsCommand.h (renamed from qcwcn/wifi_hal/tdlsCommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/vendor_definitions.h (renamed from qcwcn/wifi_hal/vendor_definitions.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifi_hal.cpp (renamed from qcwcn/wifi_hal/wifi_hal.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c (renamed from qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h (renamed from qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wificonfig.cpp (renamed from qcwcn/wifi_hal/wificonfig.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/wificonfigcommand.h (renamed from qcwcn/wifi_hal/wificonfigcommand.h)0
-rwxr-xr-xlegacy/qcwcn/wifi_hal/wifihal_internal.h (renamed from qcwcn/wifi_hal/wifihal_internal.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifihal_vendor.cpp (renamed from qcwcn/wifi_hal/wifihal_vendor.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifihal_vendorcommand.h (renamed from qcwcn/wifi_hal/wifihal_vendorcommand.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifilogger.cpp (renamed from qcwcn/wifi_hal/wifilogger.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifilogger_diag.cpp (renamed from qcwcn/wifi_hal/wifilogger_diag.cpp)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifilogger_diag.h (renamed from qcwcn/wifi_hal/wifilogger_diag.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifilogger_event_defs.h (renamed from qcwcn/wifi_hal/wifilogger_event_defs.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h (renamed from qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h)0
-rw-r--r--legacy/qcwcn/wifi_hal/wifiloggercmd.h (renamed from qcwcn/wifi_hal/wifiloggercmd.h)0
-rw-r--r--legacy/qcwcn/wpa_supplicant_8_lib/Android.mk (renamed from qcwcn/wpa_supplicant_8_lib/Android.mk)0
-rw-r--r--legacy/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD (renamed from qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD)0
-rw-r--r--legacy/qcwcn/wpa_supplicant_8_lib/NOTICE (renamed from qcwcn/wpa_supplicant_8_lib/NOTICE)0
-rw-r--r--legacy/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c (renamed from qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c)0
-rw-r--r--wcn6740/Android.mk6
-rw-r--r--wcn6740/cld80211-lib/Android.mk25
-rw-r--r--wcn6740/cld80211-lib/Makefile.am27
-rw-r--r--wcn6740/cld80211-lib/cld80211-lib.pc.in10
-rw-r--r--wcn6740/cld80211-lib/cld80211_lib.c523
-rw-r--r--wcn6740/cld80211-lib/cld80211_lib.h157
-rw-r--r--wcn6740/cld80211-lib/configure.ac77
-rw-r--r--wcn6740/qcwcn/Android.mk6
-rw-r--r--wcn6740/qcwcn/config/Android.mk24
-rw-r--r--wcn6740/qcwcn/wifi_hal/Android.mk195
-rw-r--r--wcn6740/qcwcn/wifi_hal/common.cpp430
-rw-r--r--wcn6740/qcwcn/wifi_hal/common.h295
-rw-r--r--wcn6740/qcwcn/wifi_hal/cpp_bindings.cpp1029
-rw-r--r--wcn6740/qcwcn/wifi_hal/cpp_bindings.h511
-rw-r--r--wcn6740/qcwcn/wifi_hal/gscan.cpp2292
-rw-r--r--wcn6740/qcwcn/wifi_hal/gscan_event_handler.cpp1929
-rw-r--r--wcn6740/qcwcn/wifi_hal/gscan_event_handler.h99
-rw-r--r--wcn6740/qcwcn/wifi_hal/gscancommand.h158
-rw-r--r--wcn6740/qcwcn/wifi_hal/ifaceeventhandler.cpp914
-rw-r--r--wcn6740/qcwcn/wifi_hal/ifaceeventhandler.h143
-rw-r--r--wcn6740/qcwcn/wifi_hal/list.cpp76
-rw-r--r--wcn6740/qcwcn/wifi_hal/list.h72
-rw-r--r--wcn6740/qcwcn/wifi_hal/llstats.cpp1472
-rw-r--r--wcn6740/qcwcn/wifi_hal/llstatscommand.h125
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan.cpp2116
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan_cert.h243
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan_i.h1328
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan_ind.cpp1452
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan_req.cpp2028
-rw-r--r--wcn6740/qcwcn/wifi_hal/nan_rsp.cpp1006
-rw-r--r--wcn6740/qcwcn/wifi_hal/nancommand.h237
-rw-r--r--wcn6740/qcwcn/wifi_hal/nud_stats.h100
-rw-r--r--wcn6740/qcwcn/wifi_hal/pkt_stats.h674
-rw-r--r--wcn6740/qcwcn/wifi_hal/qca-vendor_copy.h12217
-rw-r--r--wcn6740/qcwcn/wifi_hal/radio_mode.cpp303
-rw-r--r--wcn6740/qcwcn/wifi_hal/radio_mode.h59
-rw-r--r--wcn6740/qcwcn/wifi_hal/rb_wrapper.cpp166
-rw-r--r--wcn6740/qcwcn/wifi_hal/rb_wrapper.h57
-rw-r--r--wcn6740/qcwcn/wifi_hal/ring_buffer.cpp607
-rw-r--r--wcn6740/qcwcn/wifi_hal/ring_buffer.h83
-rw-r--r--wcn6740/qcwcn/wifi_hal/roam.cpp412
-rw-r--r--wcn6740/qcwcn/wifi_hal/roamcommand.h49
-rw-r--r--wcn6740/qcwcn/wifi_hal/rssi_monitor.cpp371
-rw-r--r--wcn6740/qcwcn/wifi_hal/rssi_monitor.h63
-rw-r--r--wcn6740/qcwcn/wifi_hal/rtt.cpp383
-rw-r--r--wcn6740/qcwcn/wifi_hal/sync.h94
-rw-r--r--wcn6740/qcwcn/wifi_hal/tcp_params_update.cpp364
-rw-r--r--wcn6740/qcwcn/wifi_hal/tcp_params_update.h81
-rw-r--r--wcn6740/qcwcn/wifi_hal/tdls.cpp572
-rw-r--r--wcn6740/qcwcn/wifi_hal/tdlsCommand.h111
-rw-r--r--wcn6740/qcwcn/wifi_hal/vendor_definitions.h144
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifi_hal.cpp3433
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.c241
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifi_hal_ctrl/wifi_hal_ctrl.h233
-rw-r--r--wcn6740/qcwcn/wifi_hal/wificonfig.cpp1228
-rw-r--r--wcn6740/qcwcn/wifi_hal/wificonfigcommand.h111
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifihal_internal.h186
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifihal_vendor.cpp633
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifihal_vendorcommand.h78
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifilogger.cpp1518
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifilogger_diag.cpp2926
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifilogger_diag.h250
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifilogger_event_defs.h516
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifilogger_vendor_tag_defs.h135
-rw-r--r--wcn6740/qcwcn/wifi_hal/wifiloggercmd.h120
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/Android.mk76
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/MODULE_LICENSE_BSD0
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/Makefile.am26
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/NOTICE43
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/configure.ac76
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211.c5758
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.c185
-rwxr-xr-xwcn6740/qcwcn/wpa_supplicant_8_lib/driver_cmd_nl80211_extn.h99
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/qca-vendor_copy.h12055
-rw-r--r--wcn6740/qcwcn/wpa_supplicant_8_lib/wpa_driver_common_lib.h381
-rw-r--r--wcn6740/wcnss-service/Android.mk28
-rw-r--r--wcn6740/wcnss-service/wcnss_qmi_client.c135
-rw-r--r--wcn6740/wcnss-service/wcnss_qmi_client.h49
-rw-r--r--wcn6740/wcnss-service/wcnss_service.c815
147 files changed, 67255 insertions, 1 deletions
diff --git a/Android.mk b/Android.mk
index cb1010a..3711038 100644
--- a/Android.mk
+++ b/Android.mk
@@ -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(&reg->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 *)&reg->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(&reg->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 *)&reg->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(&reg->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 *)&reg->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 *)&reg->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;
+}