summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2023-04-17 00:50:39 -0700
committerLinux Build Service Account <lnxbuild@localhost>2023-04-17 00:50:39 -0700
commit89c755fb78bd25232d482c69eb4695fbe631db41 (patch)
tree2836705567f57883266950d1a2fb8dbaa1acfb5c
parent3c2834dc69a9f9c97fcdda76968b5f98f12123cb (diff)
parent45ec62566c5438c540f399b64d0e58f610e2b4db (diff)
downloadqcacld-89c755fb78bd25232d482c69eb4695fbe631db41.tar.gz
Merge 45ec62566c5438c540f399b64d0e58f610e2b4db on remote branch
Change-Id: I1049fa61e5810c71420362bffa917b17a064e966
-rw-r--r--Kbuild36
-rw-r--r--components/coap/core/inc/wlan_coap_main.h152
-rw-r--r--components/coap/core/src/wlan_coap_main.c163
-rw-r--r--components/coap/dispatcher/inc/wlan_coap_public_structs.h123
-rw-r--r--components/coap/dispatcher/inc/wlan_coap_tgt_api.h106
-rw-r--r--components/coap/dispatcher/inc/wlan_coap_ucfg_api.h89
-rw-r--r--components/coap/dispatcher/src/wlan_coap_tgt_api.c187
-rw-r--r--components/coap/dispatcher/src/wlan_coap_ucfg_api.c99
-rw-r--r--components/mlme/core/inc/wlan_mlme_main.h7
-rw-r--r--components/mlme/core/src/wlan_mlme_main.c23
-rw-r--r--components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c12
-rw-r--r--components/mlme/dispatcher/inc/cfg_mlme_generic.h26
-rw-r--r--components/mlme/dispatcher/inc/wlan_mlme_api.h22
-rw-r--r--components/mlme/dispatcher/inc/wlan_mlme_public_struct.h7
-rw-r--r--components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h21
-rw-r--r--components/mlme/dispatcher/src/wlan_mlme_api.c17
-rw-r--r--components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h2
-rw-r--r--components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c13
-rw-r--r--components/pkt_capture/core/src/wlan_pkt_capture_main.c14
-rw-r--r--components/target_if/coap/inc/target_if_coap.h55
-rw-r--r--components/target_if/coap/src/target_if_coap.c314
-rw-r--r--components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c94
-rw-r--r--components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h2
-rw-r--r--components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c20
-rw-r--r--components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h9
-rw-r--r--components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h8
-rw-r--r--components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c28
-rw-r--r--components/wmi/inc/wmi_unified_coap_api.h147
-rw-r--r--components/wmi/src/wmi_unified_coap_tlv.c430
-rw-r--r--components/wmi/src/wmi_unified_roam_tlv.c1
-rw-r--r--configs/kiwi_v2_defconfig3
-rw-r--r--configs/qca6490_defconfig3
-rw-r--r--configs/qca6750_defconfig3
-rw-r--r--core/dp/txrx3.0/dp_fisa_rx.c14
-rw-r--r--core/hdd/inc/wlan_hdd_main.h18
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c44
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c5
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c11
-rw-r--r--core/hdd/src/wlan_hdd_coap.c86
-rw-r--r--core/hdd/src/wlan_hdd_coap.h60
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c45
-rw-r--r--core/hdd/src/wlan_hdd_main.c31
-rw-r--r--core/hdd/src/wlan_hdd_stats.c9
-rw-r--r--core/hdd/src/wlan_hdd_stats.h15
-rw-r--r--core/hdd/src/wlan_hdd_tsf.c4
-rw-r--r--core/mac/inc/qwlan_version.h4
-rw-r--r--core/mac/src/pe/lim/lim_process_action_frame.c6
-rw-r--r--core/mac/src/pe/lim/lim_process_sme_req_messages.c12
-rw-r--r--core/mac/src/pe/lim/lim_send_sme_rsp_messages.c5
-rw-r--r--core/sme/inc/sme_api.h36
-rw-r--r--core/sme/inc/sme_internal.h6
-rw-r--r--core/sme/src/common/sme_api.c56
-rw-r--r--core/sme/src/qos/sme_qos.c9
-rw-r--r--core/wma/inc/wma.h2
-rw-r--r--core/wma/inc/wma_api.h3
-rw-r--r--core/wma/inc/wma_he.h27
-rw-r--r--core/wma/inc/wma_internal.h6
-rw-r--r--core/wma/src/wma_data.c53
-rw-r--r--core/wma/src/wma_dev_if.c14
-rw-r--r--core/wma/src/wma_features.c5
-rw-r--r--core/wma/src/wma_he.c29
-rw-r--r--core/wma/src/wma_main.c6
-rw-r--r--core/wma/src/wma_mgmt.c7
-rw-r--r--core/wma/src/wma_scan_roam.c9
-rw-r--r--os_if/coap/inc/wlan_cfg80211_coap.h39
-rw-r--r--os_if/coap/src/wlan_cfg80211_coap.c683
-rw-r--r--os_if/pkt_capture/src/os_if_pkt_capture.c9
67 files changed, 3298 insertions, 306 deletions
diff --git a/Kbuild b/Kbuild
index 6f42ed4dba..7a4179b0a8 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2462,6 +2462,33 @@ endif
$(call add-wlan-objs,coex,$(COEX_OBJS))
+###### COAP ########
+COAP_HDD_SRC := core/hdd/src
+COAP_OS_IF_SRC := os_if/coap/src
+COAP_TGT_SRC := components/target_if/coap/src
+COAP_CORE_SRC := components/coap/core/src
+COAP_DISPATCHER_SRC := components/coap/dispatcher/src
+COAP_WMI_SRC := components/wmi/src
+
+COAP_OS_IF_INC := -I$(WLAN_ROOT)/os_if/coap/inc
+COAP_TGT_INC := -I$(WLAN_ROOT)/components/target_if/coap/inc
+COAP_DISPATCHER_INC := -I$(WLAN_ROOT)/components/coap/dispatcher/inc
+COAP_CORE_INC := -I$(WLAN_ROOT)/components/coap/core/inc
+COAP_WMI_INC := -I$(WLAN_ROOT)/components/wmi/inc
+
+ifeq ($(CONFIG_WLAN_FEATURE_COAP), y)
+COAP_OBJS := \
+ $(COAP_HDD_SRC)/wlan_hdd_coap.o \
+ $(COAP_OS_IF_SRC)/wlan_cfg80211_coap.o \
+ $(COAP_TGT_SRC)/target_if_coap.o \
+ $(COAP_CORE_SRC)/wlan_coap_main.o \
+ $(COAP_DISPATCHER_SRC)/wlan_coap_tgt_api.o \
+ $(COAP_DISPATCHER_SRC)/wlan_coap_ucfg_api.o \
+ $(COAP_WMI_SRC)/wmi_unified_coap_tlv.o
+endif
+
+$(call add-wlan-objs,coap,$(COAP_OBJS))
+
############## HTC ##########
HTC_DIR := htc
HTC_INC := -I$(WLAN_COMMON_INC)/$(HTC_DIR)
@@ -2978,6 +3005,12 @@ INCS += $(COEX_OS_IF_INC)
INCS += $(COEX_TGT_INC)
INCS += $(COEX_DISPATCHER_INC)
INCS += $(COEX_CORE_INC)
+################ COAP ################
+INCS += $(COAP_OS_IF_INC)
+INCS += $(COAP_TGT_INC)
+INCS += $(COAP_DISPATCHER_INC)
+INCS += $(COAP_CORE_INC)
+INCS += $(COAP_WMI_INC)
ccflags-y += $(INCS)
@@ -4341,6 +4374,9 @@ ifeq ($(CONFIG_DP_HW_TX_DELAY_STATS_ENABLE), y)
cppflags-y += -DHW_TX_DELAY_STATS_ENABLE
endif
+# Flag to enable Constrained Application Protocol feature
+cppflags-$(CONFIG_WLAN_FEATURE_COAP) += -DWLAN_FEATURE_COAP
+
KBUILD_CPPFLAGS += $(cppflags-y)
# Currently, for versions of gcc which support it, the kernel Makefile
diff --git a/components/coap/core/inc/wlan_coap_main.h b/components/coap/core/inc/wlan_coap_main.h
new file mode 100644
index 0000000000..739e027dea
--- /dev/null
+++ b/components/coap/core/inc/wlan_coap_main.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains declarations for CoAP core functions
+ */
+
+#ifndef _WLAN_COAP_MAIN_H_
+#define _WLAN_COAP_MAIN_H_
+
+#ifdef WLAN_FEATURE_COAP
+#include "wlan_objmgr_vdev_obj.h"
+
+#define coap_err(params...) \
+ QDF_TRACE_ERROR(QDF_MODULE_ID_COAP, params)
+#define coap_info(params...) \
+ QDF_TRACE_INFO(QDF_MODULE_ID_COAP, params)
+#define coap_debug(params...) \
+ QDF_TRACE_DEBUG(QDF_MODULE_ID_COAP, params)
+
+/**
+ * struct wlan_coap_comp_priv - CoAP component private structure
+ * @req_id: cache get request id
+ * @cache_get_cbk: Callback function to be called with the cache get result
+ * @cache_get_context: context to be used by the caller to associate the get
+ * cache request with the response
+ */
+struct wlan_coap_comp_priv {
+ uint32_t req_id;
+ coap_cache_get_callback cache_get_cbk;
+ void *cache_get_context;
+};
+
+static inline struct wlan_coap_comp_priv *
+wlan_get_vdev_coap_obj(struct wlan_objmgr_vdev *vdev)
+{
+ return wlan_objmgr_vdev_get_comp_private_obj(vdev,
+ WLAN_UMAC_COMP_COAP);
+}
+
+/*
+ * wlan_coap_init() - CoAP module initialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coap_init(void);
+
+/*
+ * wlan_coap_init() - CoAP module deinitialization API
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_coap_deinit(void);
+
+/**
+ * wlan_coap_enable(): API to enable CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc enable.
+ * This API will register CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_coap_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coap_disable(): API to disable CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API is invoked from dispatcher psoc disable.
+ * This API will unregister CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_coap_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_coap_offload_reply_enable() - private API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param);
+
+/**
+ * wlan_coap_offload_reply_disable() - private API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache info
+ * @context: context to be used by the caller to associate the disable request
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context);
+
+/**
+ * wlan_coap_offload_periodic_tx_enable() - private API to enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param);
+
+/**
+ * wlan_coap_offload_periodic_tx_disable() - private API to disable CoAP
+ * offload periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id);
+
+/**
+ * wlan_coap_offload_cache_get() - private API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+wlan_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context);
+#endif
+#endif
diff --git a/components/coap/core/src/wlan_coap_main.c b/components/coap/core/src/wlan_coap_main.c
new file mode 100644
index 0000000000..197a5cbf55
--- /dev/null
+++ b/components/coap/core/src/wlan_coap_main.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains definitions for CoAP core functions
+ */
+
+#include <wlan_coap_tgt_api.h>
+#include <wlan_coap_main.h>
+#include <wlan_objmgr_global_obj.h>
+
+QDF_STATUS wlan_coap_enable(struct wlan_objmgr_psoc *psoc)
+{
+ return tgt_coap_attach(psoc);
+}
+
+QDF_STATUS wlan_coap_disable(struct wlan_objmgr_psoc *psoc)
+{
+ return tgt_coap_detach(psoc);
+}
+
+static QDF_STATUS
+wlan_coap_vdev_obj_create_handler(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+ struct wlan_coap_comp_priv *coap_priv;
+ QDF_STATUS status;
+
+ if (!vdev)
+ return QDF_STATUS_E_INVAL;
+
+ coap_priv = qdf_mem_malloc(sizeof(struct wlan_coap_comp_priv));
+ if (!coap_priv)
+ return QDF_STATUS_E_NOMEM;
+
+ status = wlan_objmgr_vdev_component_obj_attach(vdev,
+ WLAN_UMAC_COMP_COAP,
+ (void *)coap_priv,
+ QDF_STATUS_SUCCESS);
+ if (QDF_IS_STATUS_ERROR(status))
+ qdf_mem_free(coap_priv);
+
+ return status;
+}
+
+static QDF_STATUS
+wlan_coap_vdev_obj_destroy_handler(struct wlan_objmgr_vdev *vdev, void *arg)
+{
+ void *coap_priv;
+
+ if (!vdev) {
+ coap_err("Vdev NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coap_priv = wlan_get_vdev_coap_obj(vdev);
+ if (!coap_priv) {
+ coap_err("coap_priv NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_COAP,
+ coap_priv);
+ qdf_mem_free(coap_priv);
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_coap_init(void)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+ wlan_coap_vdev_obj_create_handler, NULL);
+ if (status != QDF_STATUS_SUCCESS)
+ return status;
+
+ status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_COAP,
+ wlan_coap_vdev_obj_destroy_handler, NULL);
+ if (QDF_IS_STATUS_SUCCESS(status))
+ return status;
+
+ wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+ wlan_coap_vdev_obj_create_handler, NULL);
+ return status;
+}
+
+QDF_STATUS wlan_coap_deinit(void)
+{
+ wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_COAP,
+ wlan_coap_vdev_obj_create_handler, NULL);
+ wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_COAP,
+ wlan_coap_vdev_obj_destroy_handler, NULL);
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *params)
+{
+ return tgt_send_coap_offload_reply_enable(vdev, params);
+}
+
+QDF_STATUS
+wlan_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context)
+{
+ struct wlan_coap_comp_priv *coap_priv;
+
+ if (!vdev) {
+ coap_err("Vdev NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coap_priv = wlan_get_vdev_coap_obj(vdev);
+ coap_priv->req_id = req_id;
+ coap_priv->cache_get_context = context;
+ coap_priv->cache_get_cbk = cbk;
+ return tgt_send_coap_offload_reply_disable(vdev, req_id);
+}
+
+QDF_STATUS
+wlan_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *params)
+{
+ return tgt_send_coap_offload_periodic_tx_enable(vdev, params);
+}
+
+QDF_STATUS
+wlan_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ return tgt_send_coap_offload_periodic_tx_disable(vdev, req_id);
+}
+
+QDF_STATUS
+wlan_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context)
+{
+ struct wlan_coap_comp_priv *coap_priv;
+
+ if (!vdev) {
+ coap_err("Vdev NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coap_priv = wlan_get_vdev_coap_obj(vdev);
+ coap_priv->req_id = req_id;
+ coap_priv->cache_get_context = context;
+ coap_priv->cache_get_cbk = cbk;
+ return tgt_send_coap_offload_cache_get(vdev, req_id);
+}
diff --git a/components/coap/dispatcher/inc/wlan_coap_public_structs.h b/components/coap/dispatcher/inc/wlan_coap_public_structs.h
new file mode 100644
index 0000000000..63ac51b1e2
--- /dev/null
+++ b/components/coap/dispatcher/inc/wlan_coap_public_structs.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains CoAP structure definitions
+ */
+
+#ifndef _WLAN_COAP_PUBLIC_STRUCTS_H_
+#define _WLAN_COAP_PUBLIC_STRUCTS_H_
+#include <qdf_types.h>
+
+/**
+ * struct coap_offload_reply_param - parameters to enable CoAP offload reply
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ * @cache_timeout: the cached packet expire timeout in ms
+ * @src_ip_v4: source IPv4 address for sending reply message
+ * @src_udp_port: source udp port for sending reply message
+ * @dest_ip_v4: destination IPv4 address to match recived CoAP message
+ * @dest_ip_v4_is_bc: indicate whether the destination address is broadcast
+ * address or not
+ * @dest_udp_port: destination UDP port to match recived CoAP message
+ * @verify_offset: UDP payload offset to match recived CoAP message
+ * @verify_len: UDP payload length to match recived CoAP message
+ * @verify: pointer to binary data to match recived CoAP message
+ * @coapmsg_len: CoAP reply message length
+ * @coapmsg: pointer to CoAP reply message
+ */
+struct coap_offload_reply_param {
+ uint32_t vdev_id;
+ uint32_t pattern_id;
+ uint32_t cache_timeout;
+ uint32_t src_ip_v4;
+ uint16_t src_udp_port;
+ uint32_t dest_ip_v4;
+ bool dest_ip_v4_is_bc;
+ uint16_t dest_udp_port;
+ uint32_t verify_offset;
+ uint32_t verify_len;
+ uint8_t *verify;
+ uint32_t coapmsg_len;
+ uint8_t *coapmsg;
+};
+
+/**
+ * struct coap_offload_periodic_tx_param - parameters to enable CoAP offload
+ * periodic tranmitting
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ * @src_ip_v4: IPv4 address for sending CoAP message
+ * @src_udp_port: source udp port for sending CoAP message
+ * @dest_ip_v4: destination IPv4 address for sending CoAP message
+ * @dest_ip_v4_is_bc: indicate whether the destination address is broadcast
+ * address or not
+ * @dest_udp_port: destination UDP port for sending CoAP message
+ * @timeout: the periorid to send keepalive message in ms
+ * @coapmsg_len: keeplive CoAP message length
+ * @coapmsg: pointer to keeplive CoAP message
+ */
+struct coap_offload_periodic_tx_param {
+ uint32_t vdev_id;
+ uint32_t pattern_id;
+ uint32_t src_ip_v4;
+ uint16_t src_udp_port;
+ uint32_t dest_ip_v4;
+ bool dest_ip_v4_is_bc;
+ uint16_t dest_udp_port;
+ uint32_t timeout;
+ uint32_t coapmsg_len;
+ uint8_t *coapmsg;
+};
+
+/**
+ * struct coap_buf_node - CoAP message info entry
+ * @node: List entry element
+ * @tsf: TSF of the CoAP meesage
+ * @src_ip: source IPv4 address of the CoAP message
+ * @len: length of the payload
+ * @payload: pointer to buffer holding UDP payload of the CoAP message
+ */
+struct coap_buf_node {
+ qdf_list_node_t node;
+ uint64_t tsf;
+ uint32_t src_ip;
+ uint32_t len;
+ uint8_t *payload;
+};
+
+/**
+ * struct coap_buf_info - info of the cached CoAP messages
+ * @vdev_id: vdev id
+ * @req_id: request id
+ * @more_info: flag to indicate whether there are more cached messages
+ * @info_list: list to hold cached CoAP messages
+ */
+struct coap_buf_info {
+ uint8_t vdev_id;
+ uint32_t req_id;
+ bool more_info;
+ qdf_list_t info_list;
+};
+
+/**
+ * typedef coap_cache_get_callback() - callback for getting cached CoAP messages
+ * @context: context for getting cached CoAP messages
+ * @info: pointer to info of the cached CoAP messages
+ */
+typedef void (*coap_cache_get_callback)(void *context,
+ struct coap_buf_info *info);
+#endif
diff --git a/components/coap/dispatcher/inc/wlan_coap_tgt_api.h b/components/coap/dispatcher/inc/wlan_coap_tgt_api.h
new file mode 100644
index 0000000000..9f324f678a
--- /dev/null
+++ b/components/coap/dispatcher/inc/wlan_coap_tgt_api.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains CoAP south bound interface definitions
+ */
+
+#ifndef _WLAN_COAP_TGT_API_H_
+#define _WLAN_COAP_TGT_API_H_
+
+#ifdef WLAN_FEATURE_COAP
+#include <qdf_types.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+
+/**
+ * tgt_coap_attach(): attach CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API will register CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS tgt_coap_attach(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_coap_detach(): detach CoAP component
+ * @psoc: pointer to psoc
+ *
+ * This API will unregister CoAP related WMI event handlers.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS tgt_coap_detach(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * tgt_send_coap_offload_reply_enable() - enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param);
+
+/**
+ * tgt_send_coap_offload_reply_disable() - disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id);
+
+/**
+ * tgt_send_coap_offload_periodic_tx_enable() - enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP periodic transmitting
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param);
+
+/**
+ * tgt_send_coap_offload_periodic_tx_disable() - disable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id);
+
+/**
+ * wlan_coap_offload_cache_get() - get cached CoAP messages
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_send_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id);
+#endif
+#endif
diff --git a/components/coap/dispatcher/inc/wlan_coap_ucfg_api.h b/components/coap/dispatcher/inc/wlan_coap_ucfg_api.h
new file mode 100644
index 0000000000..16de679cd2
--- /dev/null
+++ b/components/coap/dispatcher/inc/wlan_coap_ucfg_api.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains CoAP north bound interface declarations
+ */
+
+#ifndef _WLAN_COAP_UCFG_API_H_
+#define _WLAN_COAP_UCFG_API_H_
+
+#include "qdf_status.h"
+#include <wlan_objmgr_vdev_obj.h>
+#include "wlan_coap_public_structs.h"
+
+#ifdef WLAN_FEATURE_COAP
+/**
+ * ucfg_coap_offload_reply_enable() - API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param);
+
+/**
+ * ucfg_coap_offload_reply_disable() - API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context);
+
+/**
+ * ucfg_coap_offload_periodic_tx_enable() - API to enable CoAP offload
+ * periodic transmit
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param);
+
+/**
+ * ucfg_coap_offload_periodic_tx_disable() - API to disable CoAP offload
+ * periodic transmit
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id);
+
+/**
+ * ucfg_coap_offload_cache_get() - API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context);
+#endif
+#endif
diff --git a/components/coap/dispatcher/src/wlan_coap_tgt_api.c b/components/coap/dispatcher/src/wlan_coap_tgt_api.c
new file mode 100644
index 0000000000..839080028e
--- /dev/null
+++ b/components/coap/dispatcher/src/wlan_coap_tgt_api.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains CoAP south bound interface definitions
+ */
+
+#include <wlan_coap_main.h>
+#include <wlan_coap_tgt_api.h>
+#include <wlan_lmac_if_def.h>
+#include "wlan_objmgr_pdev_obj.h"
+
+static inline struct wlan_lmac_if_coap_tx_ops *
+wlan_psoc_get_coap_txops(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_lmac_if_tx_ops *tx_ops;
+
+ tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+ if (!tx_ops) {
+ coap_err("tx_ops is NULL");
+ return NULL;
+ }
+
+ return &tx_ops->coap_ops;
+}
+
+static inline struct wlan_lmac_if_coap_tx_ops *
+wlan_vdev_get_coap_txops(struct wlan_objmgr_vdev *vdev)
+{
+ struct wlan_objmgr_psoc *psoc;
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ coap_err("NULL psoc");
+ return NULL;
+ }
+
+ return wlan_psoc_get_coap_txops(psoc);
+}
+
+QDF_STATUS tgt_coap_attach(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_tx_ops;
+
+ if (!psoc) {
+ coap_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_tx_ops = wlan_psoc_get_coap_txops(psoc);
+ if (!coap_tx_ops) {
+ coap_err("tx_ops is null!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!coap_tx_ops->attach) {
+ coap_err("attach function is null!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return coap_tx_ops->attach(psoc);
+}
+
+QDF_STATUS tgt_coap_detach(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_tx_ops;
+
+ if (!psoc) {
+ coap_err("psoc is null");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_tx_ops = wlan_psoc_get_coap_txops(psoc);
+ if (!coap_tx_ops) {
+ coap_err("tx_ops is null!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ if (!coap_tx_ops->detach) {
+ coap_err("coap_detach function is null!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ return coap_tx_ops->detach(psoc);
+}
+
+QDF_STATUS
+tgt_send_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!vdev) {
+ coap_err("NULL vdev");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_ops = wlan_vdev_get_coap_txops(vdev);
+ if (coap_ops && coap_ops->offload_reply_enable)
+ return coap_ops->offload_reply_enable(vdev, param);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!vdev) {
+ coap_err("NULL vdev");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_ops = wlan_vdev_get_coap_txops(vdev);
+ if (coap_ops && coap_ops->offload_reply_disable)
+ return coap_ops->offload_reply_disable(vdev, req_id);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!vdev) {
+ coap_err("NULL vdev");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_ops = wlan_vdev_get_coap_txops(vdev);
+ if (coap_ops && coap_ops->offload_periodic_tx_enable)
+ return coap_ops->offload_periodic_tx_enable(vdev, param);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!vdev) {
+ coap_err("NULL vdev");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_ops = wlan_vdev_get_coap_txops(vdev);
+ if (coap_ops && coap_ops->offload_periodic_tx_disable)
+ return coap_ops->offload_periodic_tx_disable(vdev, req_id);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+tgt_send_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!vdev) {
+ coap_err("NULL vdev");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ coap_ops = wlan_vdev_get_coap_txops(vdev);
+ if (coap_ops && coap_ops->offload_cache_get)
+ return coap_ops->offload_cache_get(vdev, req_id);
+
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/components/coap/dispatcher/src/wlan_coap_ucfg_api.c b/components/coap/dispatcher/src/wlan_coap_ucfg_api.c
new file mode 100644
index 0000000000..301621d39e
--- /dev/null
+++ b/components/coap/dispatcher/src/wlan_coap_ucfg_api.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DOC: contains CoAP north bound interface definitions
+ */
+
+#include <wlan_coap_main.h>
+#include <wlan_coap_ucfg_api.h>
+
+/**
+ * ucfg_coap_offload_reply_enable() - API to enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters of CoAP offload reply
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param)
+{
+ return wlan_coap_offload_reply_enable(vdev, param);
+}
+
+/**
+ * ucfg_coap_offload_reply_disable() - API to disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache info
+ * @context: context to be used by the caller to associate the disable request
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context)
+{
+ return wlan_coap_offload_reply_disable(vdev, req_id, cbk, context);
+}
+
+/**
+ * ucfg_coap_offload_periodic_tx_enable() - API to enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP periodic transmit
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param)
+{
+ return wlan_coap_offload_periodic_tx_enable(vdev, param);
+}
+
+/**
+ * ucfg_coap_offload_periodic_tx_disable() - private API to disable CoAP
+ * offload periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ return wlan_coap_offload_periodic_tx_disable(vdev, req_id);
+}
+
+/**
+ * ucfg_coap_offload_cache_get() - API to get CoAP offload cache
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @cbk: callback function to be called with the cache get result
+ * @context: context to be used by the caller to associate the get
+ * cache request with the response
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+ucfg_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev, uint32_t req_id,
+ coap_cache_get_callback cbk, void *context)
+{
+ return wlan_coap_offload_cache_get(vdev, req_id, cbk, context);
+}
diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h
index 4bd38372d3..2a166dee44 100644
--- a/components/mlme/core/inc/wlan_mlme_main.h
+++ b/components/mlme/core/inc/wlan_mlme_main.h
@@ -38,6 +38,8 @@
#define JOIN_PROBE_REQ_TIMER_MS 200
#define MAX_JOIN_PROBE_REQ 5
+#define MAX_WAKELOCK_FOR_BSS_COLOR_CHANGE 2000
+
/*
* Following time is used to program WOW_TIMER_PATTERN to FW so that FW will
* wake host up to do graceful disconnect in case PEER remains un-authorized
@@ -447,6 +449,9 @@ struct mlme_ap_config {
* @is_usr_ps_enabled: Is Power save enabled
* @notify_co_located_ap_upt_rnr: Notify co located AP to update RNR or not
* @mlme_ap: SAP related vdev private configurations
+ * @bss_color_change_wakelock: wakelock to complete bss color change
+ * operation on bss color collision detection
+ * @bss_color_change_runtime_lock: runtime lock to complete bss color change
*/
struct mlme_legacy_priv {
bool chan_switch_in_progress;
@@ -492,6 +497,8 @@ struct mlme_legacy_priv {
bool is_usr_ps_enabled;
bool notify_co_located_ap_upt_rnr;
struct mlme_ap_config mlme_ap;
+ qdf_wake_lock_t bss_color_change_wakelock;
+ qdf_runtime_lock_t bss_color_change_runtime_lock;
};
/**
diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c
index 93242060cb..1e08d1ac58 100644
--- a/components/mlme/core/src/wlan_mlme_main.c
+++ b/components/mlme/core/src/wlan_mlme_main.c
@@ -445,6 +445,28 @@ static void mlme_init_wds_config_cfg(struct wlan_objmgr_psoc *psoc,
}
#endif
+#ifdef CONFIG_BAND_6GHZ
+/**
+ * mlme_init_standard_6ghz_conn_policy() - initialize standard 6GHz
+ * policy connection flag
+ * @psoc: Pointer to PSOC
+ * @gen: pointer to generic CFG items
+ *
+ * Return: None
+ */
+static void mlme_init_standard_6ghz_conn_policy(struct wlan_objmgr_psoc *psoc,
+ struct wlan_mlme_generic *gen)
+{
+ gen->std_6ghz_conn_policy =
+ cfg_get(psoc, CFG_6GHZ_STANDARD_CONNECTION_POLICY);
+}
+#else
+static void mlme_init_standard_6ghz_conn_policy(struct wlan_objmgr_psoc *psoc,
+ struct wlan_mlme_generic *gen)
+{
+}
+#endif
+
/**
* mlme_init_mgmt_hw_tx_retry_count_cfg() - initialize mgmt hw tx retry count
* @psoc: Pointer to PSOC
@@ -554,6 +576,7 @@ static void mlme_init_generic_cfg(struct wlan_objmgr_psoc *psoc,
cfg_get(psoc, CFG_ENABLE_HE_MCS0_MGMT_6GHZ);
mlme_init_wds_config_cfg(psoc, gen);
mlme_init_mgmt_hw_tx_retry_count_cfg(psoc, gen);
+ mlme_init_standard_6ghz_conn_policy(psoc, gen);
}
static void mlme_init_edca_ani_cfg(struct wlan_objmgr_psoc *psoc,
diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c
index 8cc49c83f2..357b79b9ec 100644
--- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c
+++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1309,6 +1309,10 @@ static void mlme_ext_handler_destroy(struct vdev_mlme_obj *vdev_mlme)
{
if (!vdev_mlme || !vdev_mlme->ext_vdev_ptr)
return;
+ qdf_runtime_lock_deinit(
+ &vdev_mlme->ext_vdev_ptr->bss_color_change_runtime_lock);
+ qdf_wake_lock_destroy(
+ &vdev_mlme->ext_vdev_ptr->bss_color_change_wakelock);
mlme_free_self_disconnect_ies(vdev_mlme->vdev);
mlme_free_peer_disconnect_ies(vdev_mlme->vdev);
mlme_free_sae_auth_retry(vdev_mlme->vdev);
@@ -1340,6 +1344,12 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme)
mlme_init_wait_for_key_timer(vdev_mlme->vdev,
&vdev_mlme->ext_vdev_ptr->wait_key_timer);
+ qdf_wake_lock_create(
+ &vdev_mlme->ext_vdev_ptr->bss_color_change_wakelock,
+ "bss_color_change_wakelock");
+ qdf_runtime_lock_init(
+ &vdev_mlme->ext_vdev_ptr->bss_color_change_runtime_lock);
+
sme_get_vdev_type_nss(wlan_vdev_mlme_get_opmode(vdev_mlme->vdev),
&vdev_mlme->proto.generic.nss_2g,
&vdev_mlme->proto.generic.nss_5g);
diff --git a/components/mlme/dispatcher/inc/cfg_mlme_generic.h b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
index 95c06807b9..85d62692e0 100644
--- a/components/mlme/dispatcher/inc/cfg_mlme_generic.h
+++ b/components/mlme/dispatcher/inc/cfg_mlme_generic.h
@@ -180,6 +180,29 @@ enum wlan_wds_mode {
0, \
"rf test mode Enable Flag")
+#ifdef CONFIG_BAND_6GHZ
+/*
+ * standard_6ghz_connection_policy - Enable 6 GHz standard connection policy
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to set standard 6 GHz policies where STA will be
+ * allowed to scan and connect to any 6 GHz AP.
+ *
+ * Related: None
+ *
+ * Supported Feature: STA
+ */
+#define CFG_6GHZ_STANDARD_CONNECTION_POLICY CFG_INI_BOOL( \
+ "standard_6ghz_connection_policy", \
+ 1, \
+ "6ghz standard 6 GHZ connection policy")
+#define CFG_6GHZ_STD_CONN_POLICY CFG(CFG_6GHZ_STANDARD_CONNECTION_POLICY)
+#else
+#define CFG_6GHZ_STD_CONN_POLICY
+#endif
+
/*
* <ini>
* BandCapability - Preferred band (0: 2.4G, 5G, and 6G,
@@ -994,5 +1017,6 @@ enum wlan_wds_mode {
CFG(CFG_RF_TEST_MODE_SUPP_ENABLED) \
CFG_WDS_MODE_ALL \
CFG(CFG_TX_RETRY_MULTIPLIER) \
- CFG(CFG_MGMT_FRAME_HW_TX_RETRY_COUNT)
+ CFG(CFG_MGMT_FRAME_HW_TX_RETRY_COUNT)\
+ CFG_6GHZ_STD_CONN_POLICY
#endif /* __CFG_MLME_GENERIC_H */
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h
index b9a6d954d7..d7fd35d32d 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h
@@ -2255,6 +2255,28 @@ wlan_mlme_is_rf_test_mode_enabled(struct wlan_objmgr_psoc *psoc, bool *value);
QDF_STATUS
wlan_mlme_set_rf_test_mode_enabled(struct wlan_objmgr_psoc *psoc, bool value);
+#ifdef CONFIG_BAND_6GHZ
+/**
+ * wlan_mlme_is_standard_6ghz_conn_policy_enabled() - Get the 6 GHz standard
+ * connection policy flag
+ * @psoc: psoc context
+ * @value: Enable/Disable value ptr.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_mlme_is_standard_6ghz_conn_policy_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value);
+#else
+static inline QDF_STATUS
+wlan_mlme_is_standard_6ghz_conn_policy_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value)
+{
+ *value = false;
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
/**
* wlan_mlme_get_sta_miracast_mcc_rest_time() - Get STA/MIRACAST MCC rest time
*
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
index 2b8e9c91bb..5fcd49c494 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h
@@ -1341,6 +1341,7 @@ enum mlme_cfg_frame_type {
* @dual_sta_policy_cfg: Dual STA policies configuration
* @tx_retry_multiplier: TX xretry extension parameter
* @mgmt_hw_tx_retry_count: MGMT HW tx retry count for frames
+ * @std_6ghz_conn_policy: 6GHz standard connection policy
* @safe_mode_enable: safe mode to bypass some strict 6 GHz checks for
* connection, bypass strict power levels
*/
@@ -1391,6 +1392,9 @@ struct wlan_mlme_generic {
struct dual_sta_policy dual_sta_policy;
uint32_t tx_retry_multiplier;
uint8_t mgmt_hw_tx_retry_count[CFG_FRAME_TYPE_MAX];
+#ifdef CONFIG_BAND_6GHZ
+ bool std_6ghz_conn_policy;
+#endif
bool safe_mode_enable;
};
@@ -1835,6 +1839,8 @@ struct fw_scan_channels {
* are already scanned as part of partial scan.
* @roam_full_scan_6ghz_on_disc: Include the 6 GHz channels in roam full scan
* only on prior discovery of any 6 GHz support in the environment.
+ * @disconnect_on_nud_roam_invoke_fail: indicate whether disconnect ap when
+ * roam invoke fail on nud.
*/
struct wlan_mlme_lfr_cfg {
bool mawc_roam_enabled;
@@ -1958,6 +1964,7 @@ struct wlan_mlme_lfr_cfg {
uint16_t roam_ho_delay_config;
uint8_t exclude_rm_partial_scan_freq;
uint8_t roam_full_scan_6ghz_on_disc;
+ bool disconnect_on_nud_roam_invoke_fail;
};
/**
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
index 6d47f5476a..0cc74effd1 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -2797,8 +2797,25 @@ ucfg_mlme_set_rf_test_mode_enabled(struct wlan_objmgr_psoc *psoc, bool value)
}
/**
+ * ucfg_mlme_is_standard_6ghz_conn_policy_enabled() - Get 6ghz standard
+ * connection policy flag
+ * @psoc: pointer to psoc object
+ * @value: pointer to hold the value of flag
+ *
+ * Inline UCFG API to be used by HDD/OSIF callers
+ *
+ * Return: QDF Status
+ */
+static inline QDF_STATUS
+ucfg_mlme_is_standard_6ghz_conn_policy_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value)
+{
+ return wlan_mlme_is_standard_6ghz_conn_policy_enabled(psoc, value);
+}
+
+/**
* ucfg_mlme_get_opr_rate() - Get operational rate set
- * @psoc: pointer to vdev object
+ * @vdev: pointer to vdev object
* @buf: buffer to get rates set
* @len: length of the buffer
*
diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c
index bb348c24f0..9cec0867e8 100644
--- a/components/mlme/dispatcher/src/wlan_mlme_api.c
+++ b/components/mlme/dispatcher/src/wlan_mlme_api.c
@@ -3070,6 +3070,23 @@ wlan_mlme_set_rf_test_mode_enabled(struct wlan_objmgr_psoc *psoc, bool value)
return QDF_STATUS_SUCCESS;
}
+#ifdef CONFIG_BAND_6GHZ
+QDF_STATUS
+wlan_mlme_is_standard_6ghz_conn_policy_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value)
+{
+ struct wlan_mlme_psoc_ext_obj *mlme_obj;
+
+ mlme_obj = mlme_get_psoc_ext_obj(psoc);
+ if (!mlme_obj)
+ return QDF_STATUS_E_FAILURE;
+
+ *value = mlme_obj->cfg.gen.std_6ghz_conn_policy;
+
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
QDF_STATUS
wlan_mlme_cfg_set_vht_chan_width(struct wlan_objmgr_psoc *psoc, uint8_t value)
{
diff --git a/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h b/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h
index af65f8b0ea..25683fff82 100644
--- a/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h
+++ b/components/pkt_capture/core/inc/wlan_pkt_capture_data_txrx.h
@@ -43,6 +43,8 @@
#define IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN 0x0200
#endif
+#define HAL_TX_PKT_TYPE_11B 1
+
/**
* pkt_capture_data_process_type - data pkt types to process
* for packet capture mode
diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c
index 554ab6ee87..cd17d86c6b 100644
--- a/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c
+++ b/components/pkt_capture/core/src/wlan_pkt_capture_data_txrx.c
@@ -116,6 +116,7 @@ static unsigned char pkt_capture_get_tx_rate(
case 0x0:
ret = 0x16;
*preamble = LONG_PREAMBLE;
+ break;
case 0x1:
ret = 0xB;
*preamble = LONG_PREAMBLE;
@@ -180,12 +181,14 @@ static void pkt_capture_tx_get_phy_info(
mcs = 8 + pktcapture_hdr->mcs;
else
mcs = pktcapture_hdr->mcs;
+
+ tx_status->ht_mcs = mcs;
break;
case 0x3:
tx_status->vht_flags = 1;
mcs = pktcapture_hdr->mcs;
tx_status->vht_flag_values3[0] =
- mcs << 0x4 | (pktcapture_hdr->nss + 1);
+ mcs << 0x4 | (pktcapture_hdr->nss);
tx_status->vht_flag_values2 = pktcapture_hdr->bw;
break;
case 0x4:
@@ -206,9 +209,9 @@ static void pkt_capture_tx_get_phy_info(
break;
}
- if (preamble == 0)
+ if (preamble_type != HAL_TX_PKT_TYPE_11B)
tx_status->ofdm_flag = 1;
- else if (preamble == 1)
+ else
tx_status->cck_flag = 1;
tx_status->mcs = mcs;
@@ -729,9 +732,9 @@ static void pkt_capture_rx_get_phy_info(void *context, void *psoc,
break;
}
- if (preamble == 0)
+ if (preamble_type != HAL_RX_PKT_TYPE_11B)
rx_status->ofdm_flag = 1;
- else if (preamble == 1)
+ else
rx_status->cck_flag = 1;
rx_status->bw = bw;
diff --git a/components/pkt_capture/core/src/wlan_pkt_capture_main.c b/components/pkt_capture/core/src/wlan_pkt_capture_main.c
index bf44d83b80..fec0996ce7 100644
--- a/components/pkt_capture/core/src/wlan_pkt_capture_main.c
+++ b/components/pkt_capture/core/src/wlan_pkt_capture_main.c
@@ -292,8 +292,8 @@ pkt_capture_process_tx_data(void *soc, void *log_data, u_int16_t vdev_id,
/* nss not available */
pktcapture_hdr.nss = 0;
pktcapture_hdr.rssi_comb = tx_comp_status.ack_frame_rssi;
- /* rate not available */
- pktcapture_hdr.rate = 0;
+ /* update rate from available mcs */
+ pktcapture_hdr.rate = tx_comp_status.mcs;
pktcapture_hdr.stbc = tx_comp_status.stbc;
pktcapture_hdr.sgi = tx_comp_status.sgi;
pktcapture_hdr.ldpc = tx_comp_status.ldpc;
@@ -1390,7 +1390,10 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
WLAN_MLME_CFG_BEACON_INTERVAL,
&bcn_interval);
- if (bcn_interval) {
+ if (bcn_interval &&
+ (vdev_priv->frame_filter.connected_beacon_interval >
+ bcn_interval || vdev_priv->
+ frame_filter.connected_beacon_interval == 0)) {
nth_beacon_value =
vdev_priv->
frame_filter.connected_beacon_interval /
@@ -1404,6 +1407,11 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
pkt_capture_err("send beacon interval fail");
return status;
}
+ } else {
+ pkt_capture_debug(
+ "Failed to set beacon interval %d, it should be >= %d",
+ vdev_priv->frame_filter.connected_beacon_interval,
+ bcn_interval);
}
}
return QDF_STATUS_SUCCESS;
diff --git a/components/target_if/coap/inc/target_if_coap.h b/components/target_if/coap/inc/target_if_coap.h
new file mode 100644
index 0000000000..6d2fd8c76f
--- /dev/null
+++ b/components/target_if/coap/inc/target_if_coap.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains CoAP target if declarations
+ */
+#ifndef __TARGET_IF_COAP_H__
+#define __TARGET_IF_COAP_H__
+
+#include <target_if.h>
+
+/**
+ * target_if_coap_register_tx_ops() - Register CoAP target_if tx ops
+ * @tx_ops: pointer to target if tx ops
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS
+target_if_coap_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops);
+
+/**
+ * target_if_coap_get_tx_ops() - get tx ops
+ * @tx_ops: pointer to target_if tx ops
+ *
+ * API to retrieve the CoAP tx ops from the psoc context
+ *
+ * Return: pointer to tx ops
+ */
+static inline struct wlan_lmac_if_coap_tx_ops *
+target_if_coap_get_tx_ops(struct wlan_objmgr_psoc *psoc)
+{
+ struct wlan_lmac_if_tx_ops *tx_ops;
+
+ tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
+ if (!tx_ops) {
+ target_if_err("tx_ops is NULL");
+ return NULL;
+ }
+ return &tx_ops->coap_ops;
+}
+
+#endif
diff --git a/components/target_if/coap/src/target_if_coap.c b/components/target_if/coap/src/target_if_coap.c
new file mode 100644
index 0000000000..4e19dec892
--- /dev/null
+++ b/components/target_if/coap/src/target_if_coap.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: contains CoAP target if functions
+ */
+#include <wlan_coap_main.h>
+#include <target_if_coap.h>
+#include <wmi_unified_coap_api.h>
+
+/**
+ * target_if_wow_coap_buf_info_event_handler() - function to handle CoAP
+ * buf info event from firmware.
+ * @scn: scn handle
+ * @data: data buffer for event
+ * @datalen: data length
+ *
+ * Return: status of operation.
+ */
+static int
+target_if_wow_coap_buf_info_event_handler(ol_scn_t scn, uint8_t *data,
+ uint32_t datalen)
+{
+ QDF_STATUS status;
+ struct wlan_objmgr_psoc *psoc;
+ struct wmi_unified *wmi_handle;
+ struct wlan_objmgr_vdev *vdev = NULL;
+ struct wlan_coap_comp_priv *coap_priv;
+ struct coap_buf_info info = {0};
+ struct coap_buf_node *cur, *next;
+
+ if (!scn || !data) {
+ coap_err("scn: 0x%pK, data: 0x%pK", scn, data);
+ return -EINVAL;
+ }
+
+ psoc = target_if_get_psoc_from_scn_hdl(scn);
+ if (!psoc) {
+ coap_err("null psoc");
+ return -EINVAL;
+ }
+
+ wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+ if (!wmi_handle) {
+ coap_err("wmi_handle is null");
+ return -EINVAL;
+ }
+
+ qdf_list_create(&info.info_list, 0);
+ status = wmi_unified_coap_extract_buf_info(wmi_handle, data,
+ &info);
+ if (QDF_IS_STATUS_ERROR(status))
+ goto out;
+
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, info.vdev_id,
+ WLAN_COAP_ID);
+ if (!vdev) {
+ coap_err("vdev is NULL, vdev_id: %d", info.vdev_id);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ coap_priv = wlan_get_vdev_coap_obj(vdev);
+ if (!coap_priv->cache_get_cbk || !coap_priv->cache_get_context) {
+ coap_err("req id %d: callback or context is NULL",
+ coap_priv->req_id);
+ status = QDF_STATUS_E_INVAL;
+ goto out;
+ }
+
+ coap_priv->cache_get_cbk(coap_priv->cache_get_context, &info);
+out:
+ qdf_list_for_each_del(&info.info_list, cur, next, node) {
+ qdf_list_remove_node(&info.info_list, &cur->node);
+ qdf_mem_free(cur->payload);
+ qdf_mem_free(cur);
+ }
+
+ if (vdev)
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_COAP_ID);
+ return qdf_status_to_os_return(status);
+}
+
+/**
+ * target_if_coap_register_event_handler() - Register CoAP related wmi events
+ * @psoc: psoc handle
+ *
+ * Register CoAP related WMI events
+ *
+ * return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_coap_register_event_handler(struct wlan_objmgr_psoc *psoc)
+{
+ QDF_STATUS ret_val;
+ struct wmi_unified *wmi_handle;
+
+ if (!psoc) {
+ coap_err("PSOC is NULL!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+ if (!wmi_handle) {
+ coap_err("wmi_handle is null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ ret_val = wmi_unified_register_event_handler(wmi_handle,
+ wmi_wow_coap_buf_info_eventid,
+ target_if_wow_coap_buf_info_event_handler,
+ WMI_RX_WORK_CTX);
+ if (QDF_IS_STATUS_ERROR(ret_val))
+ coap_err("Failed to register coap buf info event cb");
+
+ return ret_val;
+}
+
+/**
+ * target_if_coap_unregister_event_handler() - Unregister CoAP related wmi
+ * events
+ * @psoc: psoc handle
+ *
+ * Register CoAP related WMI events
+ *
+ * return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_coap_unregister_event_handler(struct wlan_objmgr_psoc *psoc)
+{
+ struct wmi_unified *wmi_handle;
+
+ if (!psoc) {
+ coap_err("PSOC is NULL!");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+ if (!wmi_handle) {
+ coap_err("wmi_handle is null");
+ return QDF_STATUS_E_INVAL;
+ }
+ wmi_unified_unregister_event_handler(wmi_handle,
+ wmi_wow_coap_buf_info_eventid);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * target_if_coap_offload_reply_enable() - enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP offload reply
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+target_if_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_reply_param *param)
+{
+ wmi_unified_t wmi_handle;
+ struct wlan_objmgr_pdev *pdev;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+ wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+ if (!wmi_handle) {
+ coap_err("Invalid PDEV WMI handle");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return wmi_unified_coap_add_pattern_cmd(wmi_handle, param);
+}
+
+/**
+ * target_if_coap_offload_reply_disable() - disable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+target_if_coap_offload_reply_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ wmi_unified_t wmi_handle;
+ struct wlan_objmgr_pdev *pdev;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+ wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+ if (!wmi_handle) {
+ coap_err("Invalid PDEV WMI handle");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return wmi_unified_coap_del_pattern_cmd(wmi_handle,
+ wlan_vdev_get_id(vdev),
+ req_id);
+}
+
+/**
+ * target_if_coap_offload_periodic_tx_enable() - enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @param: parameters for CoAP periodic transmitting
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+target_if_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ struct coap_offload_periodic_tx_param *param)
+{
+ wmi_unified_t wmi_handle;
+ struct wlan_objmgr_pdev *pdev;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+ wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+ if (!wmi_handle) {
+ coap_err("Invalid PDEV WMI handle");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return wmi_unified_coap_add_keepalive_pattern_cmd(wmi_handle, param);
+}
+
+/**
+ * target_if_coap_offload_periodic_tx_disable() - disable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+target_if_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ wmi_unified_t wmi_handle;
+ struct wlan_objmgr_pdev *pdev;
+ uint8_t vdev_id;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+ wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+ if (!wmi_handle) {
+ coap_err("Invalid PDEV WMI handle");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ vdev_id = wlan_vdev_get_id(vdev);
+ return wmi_unified_coap_del_keepalive_pattern_cmd(wmi_handle,
+ vdev_id, req_id);
+}
+
+/**
+ * target_if_coap_offload_cache_get() - get cached CoAP messages
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: status of operation
+ */
+static QDF_STATUS
+target_if_coap_offload_cache_get(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ wmi_unified_t wmi_handle;
+ struct wlan_objmgr_pdev *pdev;
+
+ pdev = wlan_vdev_get_pdev(vdev);
+ wmi_handle = GET_WMI_HDL_FROM_PDEV(pdev);
+ if (!wmi_handle) {
+ coap_err("Invalid PDEV WMI handle");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ return wmi_unified_coap_cache_get(wmi_handle, wlan_vdev_get_id(vdev),
+ req_id);
+}
+
+QDF_STATUS
+target_if_coap_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
+{
+ struct wlan_lmac_if_coap_tx_ops *coap_ops;
+
+ if (!tx_ops) {
+ coap_err("target if tx ops is NULL!");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coap_ops = &tx_ops->coap_ops;
+ coap_ops->attach = target_if_coap_register_event_handler;
+ coap_ops->detach = target_if_coap_unregister_event_handler;
+ coap_ops->offload_reply_enable =
+ target_if_coap_offload_reply_enable;
+ coap_ops->offload_reply_disable =
+ target_if_coap_offload_reply_disable;
+ coap_ops->offload_periodic_tx_enable =
+ target_if_coap_offload_periodic_tx_enable;
+ coap_ops->offload_periodic_tx_disable =
+ target_if_coap_offload_periodic_tx_disable;
+ coap_ops->offload_cache_get = target_if_coap_offload_cache_get;
+
+ return QDF_STATUS_SUCCESS;
+}
diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c
index b784b256b1..fa10015245 100644
--- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c
+++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c
@@ -1011,16 +1011,74 @@ end:
return status;
}
+static QDF_STATUS
+cm_disconnect_roam_invoke_fail(struct wlan_objmgr_vdev *vdev,
+ wlan_cm_id cm_id)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+ struct wlan_mlme_psoc_ext_obj *mlme_obj;
+ bool nud_disconnect;
+ struct wlan_objmgr_psoc *psoc;
+ uint8_t vdev_id = wlan_vdev_get_id(vdev);
+ struct rso_config *rso_cfg;
+
+ psoc = wlan_vdev_get_psoc(vdev);
+ if (!psoc) {
+ mlme_err(CM_PREFIX_FMT "psoc not found",
+ CM_PREFIX_REF(vdev_id, cm_id));
+ return QDF_STATUS_E_INVAL;
+ }
+
+ mlme_obj = mlme_get_psoc_ext_obj(psoc);
+ if (!mlme_obj)
+ return QDF_STATUS_E_NULL_VALUE;
+
+ rso_cfg = wlan_cm_get_rso_config(vdev);
+ if (!rso_cfg) {
+ mlme_err(CM_PREFIX_FMT "rso cfg not found",
+ CM_PREFIX_REF(vdev_id, cm_id));
+ return QDF_STATUS_E_NULL_VALUE;
+ }
+
+ nud_disconnect = mlme_obj->cfg.lfr.disconnect_on_nud_roam_invoke_fail;
+ mlme_debug(CM_PREFIX_FMT "disconnect on NUD %d, source %d forced roaming %d",
+ CM_PREFIX_REF(vdev_id, cm_id),
+ nud_disconnect, rso_cfg->roam_invoke_source,
+ rso_cfg->is_forced_roaming);
+
+ /*
+ * If reassoc MAC from user space is broadcast MAC as:
+ * "wpa_cli DRIVER FASTREASSOC ff:ff:ff:ff:ff:ff 0",
+ * user space invoked roaming candidate selection will base on firmware
+ * score algorithm, current connection will be kept if current AP has
+ * highest score. It is requirement from customer which can avoid
+ * ping-pong roaming.
+ */
+ if (qdf_is_macaddr_broadcast(&rso_cfg->roam_invoke_bssid)) {
+ qdf_zero_macaddr(&rso_cfg->roam_invoke_bssid);
+ return status;
+ }
+
+ if (rso_cfg->roam_invoke_source == CM_ROAMING_HOST ||
+ (rso_cfg->roam_invoke_source == CM_ROAMING_NUD_FAILURE &&
+ nud_disconnect) || rso_cfg->is_forced_roaming) {
+ rso_cfg->roam_invoke_source = CM_SOURCE_INVALID;
+ rso_cfg->is_forced_roaming = false;
+ status = mlo_disconnect(vdev, CM_ROAM_DISCONNECT,
+ REASON_USER_TRIGGERED_ROAM_FAILURE,
+ NULL);
+ }
+
+ return status;
+}
+
QDF_STATUS cm_fw_roam_invoke_fail(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id)
{
QDF_STATUS status;
struct wlan_objmgr_vdev *vdev;
- wlan_cm_id cm_id;
- enum wlan_cm_source source;
+ wlan_cm_id cm_id = CM_ID_INVALID;
struct cnx_mgr *cm_ctx;
- struct cm_roam_req *roam_req = NULL;
- struct qdf_mac_addr bssid;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
vdev_id,
@@ -1037,36 +1095,12 @@ QDF_STATUS cm_fw_roam_invoke_fail(struct wlan_objmgr_psoc *psoc,
goto error;
}
- roam_req = cm_get_first_roam_command(vdev);
- if (!roam_req) {
- mlme_err("Failed to find roam req from list");
- status = QDF_STATUS_E_FAILURE;
- goto error;
- }
-
- cm_id = roam_req->cm_id;
- source = roam_req->req.source;
- bssid = roam_req->req.bssid;
-
status = cm_sm_deliver_event(vdev, WLAN_CM_SM_EV_ROAM_INVOKE_FAIL,
sizeof(wlan_cm_id), &cm_id);
-
if (QDF_IS_STATUS_ERROR(status))
cm_remove_cmd(cm_ctx, &cm_id);
- /*
- * If reassoc MAC from user space is broadcast MAC as:
- * "wpa_cli DRIVER FASTREASSOC ff:ff:ff:ff:ff:ff 0",
- * user space invoked roaming candidate selection will base on firmware
- * score algorithm, current connection will be kept if current AP has
- * highest score. It is requirement from customer which can avoid
- * ping-pong roaming.
- */
- if (qdf_is_macaddr_broadcast(&bssid))
- mlme_debug("Keep current connection");
- else if (source == CM_ROAMING_HOST || source == CM_ROAMING_NUD_FAILURE)
- status = mlo_disconnect(vdev, CM_ROAM_DISCONNECT,
- REASON_USER_TRIGGERED_ROAM_FAILURE,
- NULL);
+
+ cm_disconnect_roam_invoke_fail(vdev, cm_id);
error:
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_SB_ID);
diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h
index 8990ecdffd..efb1aa1419 100644
--- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h
+++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_i.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
index 55f5ce4391..c004b5b430 100644
--- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
+++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c
@@ -2240,6 +2240,8 @@ cm_roam_scan_offload_fill_scan_params(struct wlan_objmgr_psoc *psoc,
/* Parameters updated after association is complete */
wlan_scan_cfg_get_passive_dwelltime(psoc,
&scan_params->dwell_time_passive);
+ wlan_scan_cfg_get_min_dwelltime_6g(psoc,
+ &scan_params->min_dwell_time_6ghz);
/*
* Here is the formula,
* T(HomeAway) = N * T(dwell) + (N+1) * T(cs)
@@ -5129,6 +5131,7 @@ QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc,
struct qdf_mac_addr connected_bssid;
uint8_t vdev_id = vdev->vdev_objmgr.vdev_id;
bool roam_offload_enabled = cm_roam_offload_enabled(psoc);
+ struct rso_config *rso_cfg;
roam_control_bitmap = mlme_get_operations_bitmap(psoc, vdev_id);
if (roam_offload_enabled && (roam_control_bitmap ||
@@ -5147,6 +5150,10 @@ QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE;
}
+ rso_cfg = wlan_cm_get_rso_config(vdev);
+ if (!rso_cfg)
+ return QDF_STATUS_E_NULL_VALUE;
+
/* Ignore BSSID and channel validation for FW host roam */
if (source == CM_ROAMING_FW)
goto send_evt;
@@ -5157,13 +5164,17 @@ QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc,
qdf_mem_free(cm_req);
return QDF_STATUS_E_NOSUPPORT;
}
+
cm_req->roam_req.req.forced_roaming = true;
+ if (source == CM_ROAMING_HOST)
+ rso_cfg->is_forced_roaming = true;
source = CM_ROAMING_NUD_FAILURE;
goto send_evt;
}
if (qdf_is_macaddr_broadcast(bssid)) {
qdf_copy_macaddr(&cm_req->roam_req.req.bssid, bssid);
+ qdf_copy_macaddr(&rso_cfg->roam_invoke_bssid, bssid);
mlme_debug("Roam only if better candidate found else stick to current AP");
goto send_evt;
}
@@ -5187,6 +5198,15 @@ QDF_STATUS cm_start_roam_invoke(struct wlan_objmgr_psoc *psoc,
send_evt:
cm_req->roam_req.req.source = source;
+ /* Storing source information in rso cfg as if FW aborts
+ * roam host will delete roam req from queue.
+ * In roam invoke failure, host will read rso cfg params
+ * information and disconnect if needed.
+ */
+ if (source == CM_ROAMING_HOST ||
+ source == CM_ROAMING_NUD_FAILURE)
+ rso_cfg->roam_invoke_source = source;
+
cm_req->roam_req.req.vdev_id = vdev_id;
/*
* For LFR3 WLAN_CM_SM_EV_ROAM_REQ will be converted to
diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h
index dfd0b0fed3..c43f48adbf 100644
--- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h
+++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h
@@ -924,10 +924,12 @@ cm_akm_roam_allowed(struct wlan_objmgr_psoc *psoc,
* cm_invalid_roam_reason_handler() - Handler for invalid roam reason
* @vdev_id: vdev id
* @notif: roam notification of type enum cm_roam_notif
+ * @reason: Notif param value from the roam event that carries trigger reason
*
* Return: QDF_STATUS
*/
-void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif);
+void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif,
+ uint32_t reason);
/**
* cm_handle_roam_reason_ho_failed() - Handler for roam due to ho failure
@@ -1044,6 +1046,7 @@ wlan_cm_get_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
* @roam_info: Roam stats from the roam stats event
* @value: Notif param value from the roam event
* @idx: TLV index in roam stats event
+ * @reason: Notif param value from the roam event that carries trigger reason
*
* Gathers the roam stats from the roam event and the roam stats event and
* sends them to hdd for filling the vendor attributes.
@@ -1054,7 +1057,7 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum roam_rt_stats_type events,
struct roam_stats_event *roam_info,
- uint32_t value, uint8_t idx);
+ uint32_t value, uint8_t idx, uint32_t reason);
/**
* cm_roam_candidate_event_handler() - CM callback to save roam
* candidate entry in scan db
@@ -1303,7 +1306,7 @@ static inline void
cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, enum roam_rt_stats_type events,
struct roam_stats_event *roam_info,
- uint32_t value, uint8_t idx)
+ uint32_t value, uint8_t idx, uint32_t reason)
{}
static inline QDF_STATUS
diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h
index e32f18cd4d..abec6f0f80 100644
--- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h
+++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h
@@ -494,6 +494,9 @@ struct owe_transition_mode_info {
* @lost_link_rssi: lost link RSSI
* @roam_sync_frame_ind: roam sync frame ind
* @roam_band_bitmask: This allows the driver to roam within this band
+ * @roam_invoke_source: roam invoke source
+ * @roam_invoke_bssid: mac address used for roam invoke
+ * @is_forced_roaming: bool value indicating if its forced roaming
*/
struct rso_config {
#ifdef WLAN_FEATURE_HOST_ROAM
@@ -540,6 +543,9 @@ struct rso_config {
int32_t lost_link_rssi;
struct roam_synch_frame_ind roam_sync_frame_ind;
uint32_t roam_band_bitmask;
+ enum wlan_cm_source roam_invoke_source;
+ struct qdf_mac_addr roam_invoke_bssid;
+ bool is_forced_roaming;
};
/**
@@ -1281,6 +1287,7 @@ struct wlan_roam_fils_params {
* @vdev_id: vdev id
* @dwell_time_passive: dwell time in msec on passive channels
* @dwell_time_active: dwell time in msec on active channels
+ * @min_dwell_time_6ghz: minimum dwell time in msec for 6 GHz channel
* @burst_duration: Burst duration time in msec
* @min_rest_time: min time in msec on the BSS channel,only valid if atleast
* one VDEV is active
@@ -1311,6 +1318,7 @@ struct wlan_roam_scan_params {
uint32_t vdev_id;
uint32_t dwell_time_passive;
uint32_t dwell_time_active;
+ uint32_t min_dwell_time_6ghz;
uint32_t burst_duration;
uint32_t min_rest_time;
uint32_t max_rest_time;
diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
index 538028158e..1eb788ef91 100644
--- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
+++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c
@@ -2500,7 +2500,8 @@ cm_handle_roam_offload_events(struct roam_offload_roam_event *roam_event)
break;
case ROAM_REASON_INVALID:
cm_invalid_roam_reason_handler(roam_event->vdev_id,
- roam_event->notif);
+ roam_event->notif,
+ roam_event->notif_params);
break;
default:
break;
@@ -3248,12 +3249,12 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id,
enum roam_rt_stats_type events,
struct roam_stats_event *roam_info,
- uint32_t value, uint8_t idx)
+ uint32_t value, uint8_t idx, uint32_t reason)
{
struct roam_stats_event *roam_event = NULL;
if (!wlan_cm_get_roam_rt_stats(psoc, ROAM_RT_STATS_ENABLE)) {
- mlme_err("Roam events stats is disabled");
+ mlme_debug("Roam events stats is disabled");
return;
}
@@ -3263,18 +3264,23 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
if (!roam_event)
return;
- if (value == WMI_ROAM_NOTIF_SCAN_START)
+ if (value == WMI_ROAM_NOTIF_SCAN_START) {
roam_event->roam_event_param.roam_scan_state =
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START;
- else if (value == WMI_ROAM_NOTIF_SCAN_END)
+ if (reason) {
+ roam_event->trigger[idx].present = true;
+ roam_event->trigger[idx].trigger_reason =
+ reason;
+ }
+ } else if (value == WMI_ROAM_NOTIF_SCAN_END) {
roam_event->roam_event_param.roam_scan_state =
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END;
+ }
- //TO DO: Add a new CB in CM and register the hdd function to it
- //And call the new CB from here.
mlme_debug("Invoke HDD roam events callback for roam "
"scan notif");
roam_event->vdev_id = vdev_id;
+ mlme_cm_osif_roam_rt_stats(roam_event, idx);
qdf_mem_free(roam_event);
break;
case ROAM_RT_STATS_TYPE_INVOKE_FAIL_REASON:
@@ -3284,11 +3290,10 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
roam_event->roam_event_param.roam_invoke_fail_reason = value;
- //TO DO: Add a new CB in CM and register the hdd function to it
- //And call the new CB from here.
mlme_debug("Invoke HDD roam events callback for roam "
"invoke fail");
roam_event->vdev_id = vdev_id;
+ mlme_cm_osif_roam_rt_stats(roam_event, idx);
qdf_mem_free(roam_event);
break;
case ROAM_RT_STATS_TYPE_ROAM_SCAN_INFO:
@@ -3299,8 +3304,7 @@ void cm_report_roam_rt_stats(struct wlan_objmgr_psoc *psoc,
mlme_debug("Invoke HDD roam events callback for roam "
"stats event");
roam_info->vdev_id = vdev_id;
- //TO DO: Add a new CB in CM and register the hdd function to it
- //And call the new CB from here.
+ mlme_cm_osif_roam_rt_stats(roam_info, idx);
}
break;
default:
@@ -3399,7 +3403,7 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
cm_report_roam_rt_stats(psoc, stats_info->vdev_id,
ROAM_RT_STATS_TYPE_ROAM_SCAN_INFO,
- stats_info, 0, i);
+ stats_info, 0, i, 0);
}
if (!stats_info->num_tlv) {
diff --git a/components/wmi/inc/wmi_unified_coap_api.h b/components/wmi/inc/wmi_unified_coap_api.h
new file mode 100644
index 0000000000..6d5150abc3
--- /dev/null
+++ b/components/wmi/inc/wmi_unified_coap_api.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Implement API's specific to CoAP component.
+ */
+
+#ifndef _WMI_UNIFIED_COAP_API_H_
+#define _WMI_UNIFIED_COAP_API_H_
+
+#include <wmi_unified_priv.h>
+
+#ifdef WLAN_FEATURE_COAP
+/**
+ * wmi_unified_coap_add_pattern_cmd() - Add pattern for CoAP offload reply
+ * @wmi_handle: wmi handle
+ * @param: parameters for CoAP offload reply
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_add_pattern_cmd(wmi_unified_t wmi_handle,
+ struct coap_offload_reply_param *param)
+{
+ if (wmi_handle->ops->send_coap_add_pattern_cmd)
+ return wmi_handle->ops->send_coap_add_pattern_cmd(wmi_handle,
+ param);
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * wmi_unified_coap_del_pattern_cmd() - Delete pattern for CoAP offload reply
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_del_pattern_cmd(wmi_unified_t wmi_handle,
+ uint8_t vdev_id, uint32_t pattern_id)
+{
+ if (wmi_handle->ops->send_coap_del_pattern_cmd)
+ return wmi_handle->ops->send_coap_del_pattern_cmd(wmi_handle,
+ vdev_id, pattern_id);
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * wmi_unified_coap_add_keepalive_pattern_cmd() - Add pattern for CoAP offload
+ * periodic transmitting
+ * @wmi_handle: wmi handle
+ * @param: parameters for CoAP offload periodic transmitting
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_add_keepalive_pattern_cmd(wmi_unified_t wmi_handle,
+ struct coap_offload_periodic_tx_param *param)
+{
+ if (wmi_handle->ops->send_coap_add_keepalive_pattern_cmd)
+ return wmi_handle->ops->send_coap_add_keepalive_pattern_cmd(
+ wmi_handle, param);
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * wmi_unified_coap_del_pattern_cmd() - Delete pattern for CoAP offload
+ * periodic transmitting
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_del_keepalive_pattern_cmd(wmi_unified_t wmi_handle,
+ uint8_t vdev_id,
+ uint32_t pattern_id)
+{
+ if (wmi_handle->ops->send_coap_del_keepalive_pattern_cmd)
+ return wmi_handle->ops->send_coap_del_keepalive_pattern_cmd(
+ wmi_handle, vdev_id, pattern_id);
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * wmi_unified_coap_del_pattern_cmd() - Get cached CoAP messages
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_cache_get(wmi_unified_t wmi_handle,
+ uint8_t vdev_id, uint32_t pattern_id)
+{
+ if (wmi_handle->ops->send_coap_cache_get_cmd)
+ return wmi_handle->ops->send_coap_cache_get_cmd(wmi_handle,
+ vdev_id, pattern_id);
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+
+/**
+ * wmi_unified_coap_extract_buf_info() - extract CoAP buf info from event
+ * @wmi_handle: wmi handle
+ * @evt_buf: pointer to event buffer
+ * @info: Pointer to hold CoAP buf info
+ *
+ * The caller needs to free any possible nodes in info->info_list
+ * regardless of failure or success.
+ *
+ * Return: status of operation
+ */
+static inline QDF_STATUS
+wmi_unified_coap_extract_buf_info(wmi_unified_t wmi_handle, void *evt_buf,
+ struct coap_buf_info *info)
+{
+ if (wmi_handle->ops->extract_coap_buf_info) {
+ return wmi_handle->ops->extract_coap_buf_info(wmi_handle,
+ evt_buf,
+ info);
+ }
+
+ return QDF_STATUS_E_NOSUPPORT;
+}
+#endif
+#endif /* _WMI_UNIFIED_ROAM_API_H_ */
diff --git a/components/wmi/src/wmi_unified_coap_tlv.c b/components/wmi/src/wmi_unified_coap_tlv.c
new file mode 100644
index 0000000000..7d724c3f89
--- /dev/null
+++ b/components/wmi/src/wmi_unified_coap_tlv.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: Implement API's specific to CoAP component.
+ */
+
+#include <wmi_unified_priv.h>
+#include "wmi.h"
+#include "ol_defines.h"
+
+/*
+ * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP pattern
+ * @wmi_handle: wmi handle
+ * @param: parameter for CoAP add pattern
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_coap_add_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+ struct coap_offload_reply_param *param)
+{
+ WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ QDF_STATUS status;
+ uint8_t *buf_ptr;
+ uint32_t len, coapmsg_len_align, verify_len_align;
+
+ wmi_debug("vdev id %d pattern id %d timeout %d src ip 0x%x:%d coap msg len %d",
+ param->vdev_id, param->pattern_id, param->cache_timeout,
+ param->src_ip_v4, param->src_udp_port,
+ param->coapmsg_len);
+
+ wmi_debug("filter: dest ip 0x%x:%d is bc %d verify offset %d len %d",
+ param->dest_ip_v4, param->dest_udp_port,
+ param->dest_ip_v4_is_bc, param->verify_offset,
+ param->verify_len);
+
+ if (!param->verify || !param->verify_len ||
+ !param->coapmsg || !param->coapmsg_len) {
+ wmi_err("invalid param");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
+ verify_len_align = qdf_align(param->verify_len, 4);
+ len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align +
+ WMI_TLV_HDR_SIZE + verify_len_align;
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf)
+ return QDF_STATUS_E_NOMEM;
+
+ buf_ptr = wmi_buf_data(buf);
+ cmd = (WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param *)buf_ptr;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_COAP_ADD_PATTERN_CMD_fixed_param));
+
+ cmd->vdev_id = param->vdev_id;
+ cmd->pattern_id = param->pattern_id;
+ cmd->timeout = param->cache_timeout;
+ WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
+ WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
+ param->dest_ip_v4_is_bc ? 1 : 0);
+ qdf_mem_copy(cmd->match_udp_ip.ipv4_addr, &param->dest_ip_v4,
+ sizeof(param->dest_ip_v4));
+ cmd->match_udp_port = param->dest_udp_port;
+ qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, &param->src_ip_v4,
+ sizeof(param->src_ip_v4));
+ cmd->udp_local_port = param->src_udp_port;
+ cmd->verify_offset = param->verify_offset;
+ cmd->verify_len = param->verify_len;
+ cmd->coapmsg_len = param->coapmsg_len;
+
+ buf_ptr += sizeof(*cmd);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, verify_len_align);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ qdf_mem_copy(buf_ptr, param->verify, param->verify_len);
+
+ buf_ptr += verify_len_align;
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
+ buf_ptr += coapmsg_len_align;
+
+ wmi_mtrace(WMI_WOW_COAP_ADD_PATTERN_CMDID,
+ cmd->vdev_id, cmd->pattern_id);
+ status = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WOW_COAP_ADD_PATTERN_CMDID);
+ if (status != QDF_STATUS_SUCCESS) {
+ wmi_err("Failed to send wow coap add pattern command %d",
+ status);
+ wmi_buf_free(buf);
+ }
+
+ return status;
+}
+
+/*
+ * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP pattern
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_coap_del_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+ uint8_t vdev_id, uint32_t pattern_id)
+{
+ WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ QDF_STATUS status;
+ uint32_t len = sizeof(*cmd);
+
+ wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
+
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf)
+ return QDF_STATUS_E_NOMEM;
+
+ cmd = (WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param *)wmi_buf_data(buf);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
+
+ cmd->vdev_id = vdev_id;
+ cmd->pattern_id = pattern_id;
+ wmi_mtrace(WMI_WOW_COAP_DEL_PATTERN_CMDID,
+ cmd->vdev_id, cmd->pattern_id);
+ status = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WOW_COAP_DEL_PATTERN_CMDID);
+ if (status != QDF_STATUS_SUCCESS) {
+ wmi_err("Failed to send wow coap del pattern command %d",
+ status);
+ wmi_buf_free(buf);
+ }
+
+ return status;
+}
+
+/*
+ * send_coap_add_pattern_cmd_tlv() - Send wmi cmd for adding CoAP keepalive
+ * pattern
+ * @wmi_handle: wmi handle
+ * @param: parameter for CoAP add pattern
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_coap_add_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+ struct coap_offload_periodic_tx_param *param)
+{
+ WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ QDF_STATUS status;
+ uint8_t *buf_ptr;
+ uint32_t len, coapmsg_len_align;
+
+ wmi_debug("vdev id %d pattern id %d ip src 0x%x:%d dest 0x%x:%d bc %d timeout %d",
+ param->vdev_id, param->pattern_id, param->src_ip_v4,
+ param->src_udp_port, param->dest_ip_v4,
+ param->dest_udp_port, param->dest_ip_v4_is_bc,
+ param->timeout);
+
+ if (!param->coapmsg || !param->coapmsg_len) {
+ wmi_err("invalid CoAP message");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ coapmsg_len_align = qdf_align(param->coapmsg_len, 4);
+ len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + coapmsg_len_align;
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf)
+ return QDF_STATUS_E_NOMEM;
+
+ buf_ptr = wmi_buf_data(buf);
+ cmd = (WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMD_fixed_param));
+
+ cmd->vdev_id = param->vdev_id;
+ cmd->pattern_id = param->pattern_id;
+
+ /* only support IPv4 in current stage */
+ WMI_COAP_IPV6_SET(cmd->pattern_type, 0);
+ WMI_COAP_ADDR_TYPE_SET(cmd->pattern_type,
+ param->dest_ip_v4_is_bc ? 1 : 0);
+ qdf_mem_copy(cmd->udp_remote_ip.ipv4_addr, &param->dest_ip_v4,
+ sizeof(param->dest_ip_v4));
+ cmd->udp_remote_port = param->dest_udp_port;
+ qdf_mem_copy(cmd->udp_local_ip.ipv4_addr, &param->src_ip_v4,
+ sizeof(param->src_ip_v4));
+ cmd->udp_local_port = param->src_udp_port;
+ cmd->timeout = param->timeout;
+ cmd->coapmsg_len = param->coapmsg_len;
+
+ buf_ptr += sizeof(*cmd);
+ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, coapmsg_len_align);
+ buf_ptr += WMI_TLV_HDR_SIZE;
+ qdf_mem_copy(buf_ptr, param->coapmsg, param->coapmsg_len);
+ buf_ptr += coapmsg_len_align;
+
+ wmi_mtrace(WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID,
+ cmd->vdev_id, cmd->pattern_id);
+ status = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WOW_COAP_ADD_KEEPALIVE_PATTERN_CMDID);
+ if (status != QDF_STATUS_SUCCESS) {
+ wmi_err("Failed to send wow coap add keepalive pattern command %d",
+ status);
+ wmi_buf_free(buf);
+ }
+
+ return status;
+}
+
+/*
+ * send_coap_del_pattern_cmd_tlv() - Send wmi cmd for deleting CoAP
+ * keepalive pattern
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_coap_del_keepalive_pattern_cmd_tlv(wmi_unified_t wmi_handle,
+ uint8_t vdev_id, uint32_t pattern_id)
+{
+ WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ QDF_STATUS status;
+ uint8_t *buf_ptr;
+ uint32_t len = sizeof(*cmd);
+
+ wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf)
+ return QDF_STATUS_E_NOMEM;
+
+ buf_ptr = wmi_buf_data(buf);
+ cmd = (WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param *)buf_ptr;
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_COAP_DEL_PATTERN_CMD_fixed_param));
+
+ cmd->vdev_id = vdev_id;
+ cmd->pattern_id = pattern_id;
+ wmi_mtrace(WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID,
+ cmd->vdev_id, cmd->pattern_id);
+ status = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WOW_COAP_DEL_KEEPALIVE_PATTERN_CMDID);
+ if (status != QDF_STATUS_SUCCESS) {
+ wmi_err("Failed to send wow coap del keepalive pattern command %d",
+ status);
+ wmi_buf_free(buf);
+ }
+
+ return status;
+}
+
+/*
+ * send_coap_cache_get_cmd_tlv() - Send wmi cmd for getting cached CoAP
+ * messages
+ * @wmi_handle: wmi handle
+ * @vdev_id: vdev id
+ * @pattern_id: pattern id
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+send_coap_cache_get_cmd_tlv(wmi_unified_t wmi_handle,
+ uint8_t vdev_id, uint32_t pattern_id)
+{
+ WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *cmd;
+ wmi_buf_t buf;
+ QDF_STATUS status;
+ uint32_t len = sizeof(*cmd);
+
+ wmi_debug("vdev id %d pattern id %d", vdev_id, pattern_id);
+ buf = wmi_buf_alloc(wmi_handle, len);
+ if (!buf)
+ return QDF_STATUS_E_NOMEM;
+
+ cmd = (WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param *)wmi_buf_data(buf);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(
+ WMI_WOW_COAP_GET_BUF_INFO_CMD_fixed_param));
+
+ cmd->vdev_id = vdev_id;
+ cmd->pattern_id = pattern_id;
+ wmi_mtrace(WMI_WOW_COAP_GET_BUF_INFO_CMDID,
+ cmd->vdev_id, cmd->pattern_id);
+ status = wmi_unified_cmd_send(wmi_handle, buf, len,
+ WMI_WOW_COAP_GET_BUF_INFO_CMDID);
+ if (status != QDF_STATUS_SUCCESS) {
+ wmi_err("Failed to send wow coap get buf info command %d",
+ status);
+ wmi_buf_free(buf);
+ }
+
+ return status;
+}
+
+/**
+ * coap_extract_buf_info_tlv() - Extract CoAP buf info event
+ * @wmi_handle: wmi handle
+ * @evt_buf: Pointer to the event buffer
+ * @info: pointer to CoAP buf info
+ *
+ * The caller needs to free any possible nodes in info->info_list
+ * regardless of failure or success.
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+coap_extract_buf_info_tlv(wmi_unified_t wmi_handle, void *evt_buf,
+ struct coap_buf_info *info)
+{
+ WMI_WOW_COAP_BUF_INFO_EVENT_fixed_param *buf_info_ev;
+ WMI_WOW_COAP_BUF_INFO_EVENTID_param_tlvs *param_buf = evt_buf;
+ wmi_coap_tuple *tuple;
+ uint8_t *payload;
+ uint32_t num_tuple, num_payload;
+ struct coap_buf_node *buf_node;
+ int i, j;
+
+ buf_info_ev = param_buf->fixed_param;
+ if (!buf_info_ev) {
+ wmi_debug("received null event data from target");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (buf_info_ev->vdev_id > WLAN_MAX_VDEVS) {
+ wmi_debug("received invalid vdev_id %d",
+ buf_info_ev->vdev_id);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ info->vdev_id = buf_info_ev->vdev_id;
+ info->req_id = buf_info_ev->pattern_id;
+ info->more_info = buf_info_ev->more_tuples;
+
+ num_tuple = param_buf->num_coap_tuple;
+ num_payload = param_buf->num_payloads;
+ for (i = 0, j = 0; i < num_tuple && j < num_payload; i++) {
+ tuple = &param_buf->coap_tuple[i];
+ if (!tuple->payload_len) {
+ wmi_err("idx %d: invalid payload len 0", i);
+ continue;
+ }
+
+ payload = &param_buf->payloads[j];
+ j += qdf_align(tuple->payload_len, 4);
+ if (j > num_payload) {
+ wmi_err("idx %d: payload len overflow, pos %d - total %d",
+ i, j, num_payload);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ buf_node = qdf_mem_malloc(sizeof(*buf_node));
+ if (!buf_node)
+ return QDF_STATUS_E_NOMEM;
+
+ buf_node->payload = qdf_mem_malloc(tuple->payload_len);
+ if (!buf_node->payload) {
+ qdf_mem_free(buf_node);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ buf_node->tsf = tuple->tsf;
+ qdf_mem_copy(&buf_node->src_ip, tuple->src_ip.ipv4_addr,
+ sizeof(buf_node->src_ip));
+ buf_node->len = tuple->payload_len;
+ qdf_mem_copy(buf_node->payload, payload, buf_node->len);
+ qdf_list_insert_back(&info->info_list, &buf_node->node);
+
+ wmi_debug("idx %d: src ip 0x%x tsf 0x%llx payload len %d",
+ i, buf_node->src_ip, buf_node->tsf, buf_node->len);
+ }
+
+ wmi_debug("vdev_id %d req_id %d num_tuple %d payload len %d more info %d",
+ info->vdev_id, info->req_id, num_tuple,
+ num_payload, info->more_info);
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wmi_coap_attach_tlv() - attach CoAP tlv handlers
+ * @wmi_handle: wmi handle
+ *
+ * Return: void
+ */
+void wmi_coap_attach_tlv(wmi_unified_t wmi_handle)
+{
+ struct wmi_ops *ops = wmi_handle->ops;
+
+ ops->send_coap_add_pattern_cmd = send_coap_add_pattern_cmd_tlv;
+ ops->send_coap_del_pattern_cmd = send_coap_del_pattern_cmd_tlv;
+ ops->send_coap_add_keepalive_pattern_cmd =
+ send_coap_add_keepalive_pattern_cmd_tlv;
+ ops->send_coap_del_keepalive_pattern_cmd =
+ send_coap_del_keepalive_pattern_cmd_tlv;
+ ops->send_coap_cache_get_cmd = send_coap_cache_get_cmd_tlv;
+ ops->extract_coap_buf_info = coap_extract_buf_info_tlv;
+}
diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c
index fcb3db27cc..e4e7353b26 100644
--- a/components/wmi/src/wmi_unified_roam_tlv.c
+++ b/components/wmi/src/wmi_unified_roam_tlv.c
@@ -4067,6 +4067,7 @@ wmi_fill_rso_start_scan_tlv(struct wlan_roam_scan_offload_params *rso_req,
scan_tlv->dwell_time_active = src_scan_params->dwell_time_active;
scan_tlv->dwell_time_passive = src_scan_params->dwell_time_passive;
+ scan_tlv->min_dwell_time_6ghz = src_scan_params->min_dwell_time_6ghz;
scan_tlv->burst_duration = src_scan_params->burst_duration;
scan_tlv->min_rest_time = src_scan_params->min_rest_time;
scan_tlv->max_rest_time = src_scan_params->max_rest_time;
diff --git a/configs/kiwi_v2_defconfig b/configs/kiwi_v2_defconfig
index 6d448dd693..8b1434ca4d 100644
--- a/configs/kiwi_v2_defconfig
+++ b/configs/kiwi_v2_defconfig
@@ -21,3 +21,6 @@ CONFIG_CHIP_VERSION := 2
#DP configs
CONFIG_WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG := y
CONFIG_WLAN_DP_DISABLE_TCL_STATUS_SRNG := y
+
+#Enable Constrained Application Protocol feature
+CONFIG_WLAN_FEATURE_COAP := y
diff --git a/configs/qca6490_defconfig b/configs/qca6490_defconfig
index 91dd00dc37..4074b79f24 100644
--- a/configs/qca6490_defconfig
+++ b/configs/qca6490_defconfig
@@ -1,2 +1,5 @@
CONFIG_CNSS_QCA6490 := y
include $(WLAN_ROOT)/configs/default_defconfig
+
+#Enable Constrained Application Protocol feature
+CONFIG_WLAN_FEATURE_COAP := y
diff --git a/configs/qca6750_defconfig b/configs/qca6750_defconfig
index 4afabfde73..48012ec022 100644
--- a/configs/qca6750_defconfig
+++ b/configs/qca6750_defconfig
@@ -1,3 +1,6 @@
CONFIG_CNSS_QCA6750 := y
$(warning "### DBG CONFIG_CNSS_QCA6750")
include $(WLAN_ROOT)/configs/default_defconfig
+
+#Enable Constrained Application Protocol feature
+CONFIG_WLAN_FEATURE_COAP := y
diff --git a/core/dp/txrx3.0/dp_fisa_rx.c b/core/dp/txrx3.0/dp_fisa_rx.c
index cd908c37d7..e847e8355a 100644
--- a/core/dp/txrx3.0/dp_fisa_rx.c
+++ b/core/dp/txrx3.0/dp_fisa_rx.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -1943,6 +1943,7 @@ QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_fisa_rx_sw_ft *fisa_flow;
int fisa_ret;
uint8_t rx_ctx_id = QDF_NBUF_CB_RX_CTX_ID(nbuf_list);
+ uint32_t tlv_reo_dest_ind;
head_nbuf = nbuf_list;
@@ -1971,6 +1972,17 @@ QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev,
qdf_nbuf_push_head(head_nbuf, soc->rx_pkt_tlv_size +
QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(head_nbuf));
+ hal_rx_msdu_get_reo_destination_indication(soc->hal_soc,
+ (uint8_t *)qdf_nbuf_data(head_nbuf),
+ &tlv_reo_dest_ind);
+ /* Skip FISA aggregation and drop the frame if RDI is REO2TCL */
+ if (qdf_unlikely(tlv_reo_dest_ind == REO_REMAP_TCL)) {
+ qdf_nbuf_free(head_nbuf);
+ head_nbuf = next_nbuf;
+ DP_STATS_INC(dp_fisa_rx_hdl, incorrect_rdi, 1);
+ continue;
+ }
+
/* Add new flow if the there is no ongoing flow */
fisa_flow = dp_rx_get_fisa_flow(dp_fisa_rx_hdl, vdev,
head_nbuf);
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index 6df474912f..df2053a0e2 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1379,8 +1379,6 @@ struct hdd_adapter {
/* Completion variable for action frame */
struct completion tx_action_cnf_event;
- struct completion sta_authorized_event;
-
/* Track whether the linkup handling is needed */
bool is_link_up_service_needed;
@@ -2694,6 +2692,19 @@ void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter,
wlan_net_dev_ref_dbgid dbgid);
/**
+ * hdd_validate_next_adapter - API to check for infinite loop
+ * in the adapter list traversal
+ * @curr: current adapter pointer
+ * @next: next adapter pointer
+ * @dbg_id: Debug ID corresponding to API that is requesting the dev_put
+ *
+ * Return: None
+ */
+void hdd_validate_next_adapter(struct hdd_adapter **curr,
+ struct hdd_adapter **next,
+ wlan_net_dev_ref_dbgid dbg_id);
+
+/**
* __hdd_take_ref_and_fetch_front_adapter_safe - Helper macro to lock, fetch
* front and next adapters, take ref and unlock.
* @hdd_ctx: the global HDD context
@@ -2724,6 +2735,7 @@ void hdd_adapter_dev_put_debug(struct hdd_adapter *adapter,
qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock), \
adapter = next_adapter, \
hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &next_adapter), \
+ hdd_validate_next_adapter(&adapter, &next_adapter, dbgid), \
(next_adapter) ? hdd_adapter_dev_hold_debug(next_adapter, dbgid) : \
(false), \
qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock)
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 2b0be5ac5c..358f6fed32 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -166,8 +166,6 @@ u8 ccp_rsn_oui_13[HDD_RSN_OUI_SIZE] = {0x50, 0x6F, 0x9A, 0x01};
#define ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
#define ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
-#define HDD_PEER_AUTHORIZE_WAIT 10
-
/*
* beacon_filter_table - table of IEs used for beacon filtering
*/
@@ -1028,39 +1026,10 @@ void hdd_clear_roam_profile_ie(struct hdd_adapter *adapter)
hdd_exit();
}
-/**
- * hdd_set_peer_authorized_event() - set peer_authorized_event
- * @vdev_id: vdevid
- *
- * Return: None
- */
-static void hdd_set_peer_authorized_event(uint32_t vdev_id)
-{
- struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
- struct hdd_adapter *adapter = NULL;
-
- if (!hdd_ctx)
- return;
-
- adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
- if (!adapter) {
- hdd_err("Invalid vdev_id");
- return;
- }
- complete(&adapter->sta_authorized_event);
-}
-
#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
static inline
void hdd_set_unpause_queue(void *soc, struct hdd_adapter *adapter)
{
- unsigned long rc;
- /* wait for event from firmware to set the event */
- rc = wait_for_completion_timeout(
- &adapter->sta_authorized_event,
- msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
- if (!rc)
- hdd_debug("timeout waiting for sta_authorized_event");
cdp_fc_vdev_unpause(soc, adapter->vdev_id,
OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED,
@@ -1128,15 +1097,9 @@ QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
/* Reset scan reject params on successful set key */
hdd_debug("Reset scan reject params");
hdd_init_scan_reject_params(adapter->hdd_ctx);
-#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
- /* make sure event is reset */
- INIT_COMPLETION(adapter->sta_authorized_event);
-#endif
- err = sme_set_peer_authorized(
- peer_mac,
- hdd_set_peer_authorized_event,
- adapter->vdev_id);
+ err = sme_set_peer_authorized(peer_mac,
+ adapter->vdev_id);
if (err != QDF_STATUS_SUCCESS) {
hdd_err("Failed to set the peer state to authorized");
return QDF_STATUS_E_FAULT;
@@ -2488,6 +2451,9 @@ struct osif_cm_ops osif_ops = {
.netif_queue_control_cb = hdd_cm_netif_queue_control,
.napi_serialize_control_cb = hdd_cm_napi_serialize_control,
.save_gtk_cb = hdd_cm_save_gtk,
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+ .roam_rt_stats_event_cb = wlan_hdd_cfg80211_roam_events_callback,
+#endif
#ifdef WLAN_FEATURE_FILS_SK
.set_hlp_data_cb = hdd_cm_set_hlp_data,
#endif
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index c2244a8130..30c53ec0b3 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1008,6 +1008,9 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx)
STA_ROAM_POLICY_DFS_ENABLED;
mlme_obj->cfg.lfr.rso_user_config.policy_params.skip_unsafe_channels = 0;
+ if (config->enable_nud_tracking == DISCONNECT_AFTER_ROAM_FAIL)
+ mlme_obj->cfg.lfr.disconnect_on_nud_roam_invoke_fail = true;
+
status = hdd_set_sme_cfgs_related_to_mlme(hdd_ctx, sme_config);
if (!QDF_IS_STATUS_SUCCESS(status))
hdd_err("hdd_set_sme_cfgs_related_to_mlme() fail: %d", status);
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 78b601a1fc..a523019e2f 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -178,6 +178,7 @@
#include "wlan_pkt_capture_ucfg_api.h"
#include "os_if_pkt_capture.h"
#include "wlan_osif_features.h"
+#include "wlan_hdd_coap.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -1794,6 +1795,7 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
.subcmd = QCA_NL80211_VENDOR_SUBCMD_UPDATE_STA_INFO,
},
FEATURE_THERMAL_VENDOR_EVENTS
+ FEATURE_DRIVER_DISCONNECT_REASON
#ifdef WLAN_SUPPORT_TWT
FEATURE_TWT_VENDOR_EVENTS
#endif
@@ -18177,6 +18179,7 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX)
},
#endif
+ FEATURE_COAP_OFFLOAD_COMMANDS
};
struct hdd_context *hdd_cfg80211_wiphy_alloc(void)
@@ -21384,6 +21387,14 @@ QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter,
if (!sta_info->is_deauth_in_progress) {
hdd_debug("Delete STA with MAC:" QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes));
+
+ if (QDF_IS_ADDR_BROADCAST(sta_info->sta_mac.bytes)) {
+ hdd_put_sta_info_ref(&adapter->sta_info_list,
+ &sta_info, true,
+ STA_INFO_SOFTAP_DEAUTH_ALL_STA);
+ continue;
+ }
+
qdf_mem_copy(param->peerMacAddr.bytes,
sta_info->sta_mac.bytes,
QDF_MAC_ADDR_SIZE);
diff --git a/core/hdd/src/wlan_hdd_coap.c b/core/hdd/src/wlan_hdd_coap.c
new file mode 100644
index 0000000000..9c3b2c9f04
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_coap.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_coap.c
+ *
+ * The implementation of CoAP offload configuration
+ *
+ */
+
+#include "wlan_hdd_main.h"
+#include "wlan_hdd_coap.h"
+#include "osif_sync.h"
+#include "wlan_hdd_object_manager.h"
+#include "wlan_cfg80211_coap.h"
+
+/**
+ * __wlan_hdd_cfg80211_coap_offload() - configure CoAP offloading
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to netlink TLV buffer
+ * @data_len: the length of @data in bytes
+ *
+ * Return: An error code or 0 on success.
+ */
+static int
+__wlan_hdd_cfg80211_coap_offload(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
+ struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
+ int errno;
+ struct wlan_objmgr_vdev *vdev;
+
+ hdd_enter_dev(wdev->netdev);
+
+ if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
+ hdd_err("Command not allowed in FTM mode");
+ return -EPERM;
+ }
+
+ errno = wlan_hdd_validate_context(hdd_ctx);
+ if (errno != 0)
+ return errno;
+
+ if (adapter->device_mode != QDF_STA_MODE)
+ return -ENOTSUPP;
+
+ vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_COAP_ID);
+ if (!vdev)
+ return -EINVAL;
+
+ errno = wlan_cfg80211_coap_offload(wiphy, vdev, data, data_len);
+ hdd_objmgr_put_vdev_by_user(vdev, WLAN_COAP_ID);
+ return errno;
+}
+
+int wlan_hdd_cfg80211_coap_offload(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int errno;
+ struct osif_vdev_sync *vdev_sync;
+
+ errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
+ if (errno)
+ return errno;
+
+ errno = __wlan_hdd_cfg80211_coap_offload(wiphy, wdev, data, data_len);
+ osif_vdev_sync_op_stop(vdev_sync);
+ return errno;
+}
diff --git a/core/hdd/src/wlan_hdd_coap.h b/core/hdd/src/wlan_hdd_coap.h
new file mode 100644
index 0000000000..c68ce562be
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_coap.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_coap.h
+ *
+ * Add Vendor subcommand QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD
+ */
+
+#ifndef __WLAN_HDD_COAP_H
+#define __WLAN_HDD_COAP_H
+
+#ifdef WLAN_FEATURE_COAP
+#include <net/cfg80211.h>
+
+/**
+ * wlan_hdd_cfg80211_coap_offload() - configure CoAP offloading
+ * @wiphy: pointer to wireless wiphy structure.
+ * @wdev: pointer to wireless_dev structure.
+ * @data: pointer to netlink TLV buffer
+ * @data_len: the length of @data in bytes
+ *
+ * Return: An error code or 0 on success.
+ */
+int wlan_hdd_cfg80211_coap_offload(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len);
+
+extern const struct nla_policy
+ coap_offload_policy[QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_MAX + 1];
+
+#define FEATURE_COAP_OFFLOAD_COMMANDS \
+{ \
+ .info.vendor_id = QCA_NL80211_VENDOR_ID, \
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_COAP_OFFLOAD, \
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+ WIPHY_VENDOR_CMD_NEED_NETDEV | \
+ WIPHY_VENDOR_CMD_NEED_RUNNING, \
+ .doit = wlan_hdd_cfg80211_coap_offload, \
+ vendor_command_policy(coap_offload_policy, \
+ QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_MAX) \
+},
+#else /* WLAN_FEATURE_COAP */
+#define FEATURE_COAP_OFFLOAD_COMMANDS
+#endif /* WLAN_FEATURE_COAP */
+
+#endif /* __WLAN_HDD_COAP_H */
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index cdf807fa5e..15d32f498c 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -3058,7 +3058,7 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
memset(&dot11_rsn_ie, 0, sizeof(tDot11fIERSN));
ret = sme_unpack_rsn_ie(mac_handle, rsn_ie, rsn_ie_len,
&dot11_rsn_ie, false);
- if (DOT11F_FAILED(ret)) {
+ if (!DOT11F_SUCCEEDED(ret)) {
hdd_err("unpack failed, 0x%x", ret);
return -EINVAL;
}
@@ -3099,7 +3099,7 @@ static int hdd_softap_unpack_ie(mac_handle_t mac_handle,
ret = dot11f_unpack_ie_wpa(MAC_CONTEXT(mac_handle),
rsn_ie, rsn_ie_len,
&dot11_wpa_ie, false);
- if (DOT11F_FAILED(ret)) {
+ if (!DOT11F_SUCCEEDED(ret)) {
hdd_err("unpack failed, 0x%x", ret);
return -EINVAL;
}
@@ -3170,6 +3170,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
QDF_STATUS status;
int ret = 0;
struct hdd_adapter *adapter = (netdev_priv(dev));
+ struct hdd_beacon_data *beacon = adapter->session.ap.beacon;
struct hdd_context *hdd_ctx = NULL;
struct hdd_adapter *sta_adapter;
struct hdd_station_ctx *sta_ctx;
@@ -3181,6 +3182,10 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
bool strict;
uint32_t sta_cnt = 0;
struct ch_params ch_params = {0};
+ const u8 *rsn_ie, *rsnxe_ie;
+ struct wlan_crypto_params crypto_params = {0};
+ bool capable, is_wps;
+ int32_t keymgmt;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ret = wlan_hdd_validate_context(hdd_ctx);
@@ -3210,6 +3215,32 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_chan_freq,
return ret;
}
+ if (WLAN_REG_IS_6GHZ_CHAN_FREQ(target_chan_freq)) {
+ rsn_ie = wlan_get_ie_ptr_from_eid(WLAN_EID_RSN,
+ beacon->tail,
+ beacon->tail_len);
+ rsnxe_ie = wlan_get_ie_ptr_from_eid(WLAN_ELEMID_RSNXE,
+ beacon->tail,
+ beacon->tail_len);
+ if (rsn_ie)
+ wlan_crypto_rsnie_check(&crypto_params, rsn_ie);
+
+ keymgmt = wlan_crypto_get_param(sap_ctx->vdev,
+ WLAN_CRYPTO_PARAM_KEY_MGMT);
+ if (keymgmt < 0) {
+ hdd_err_rl("Invalid keymgmt");
+ return -EINVAL;
+ }
+
+ is_wps = adapter->device_mode == QDF_P2P_GO_MODE ? true : false;
+ capable = wlan_cm_6ghz_allowed_for_akm(hdd_ctx->psoc, keymgmt,
+ crypto_params.rsn_caps,
+ rsnxe_ie, 0, is_wps);
+ if (!capable) {
+ hdd_err_rl("6Ghz channel switch not capable");
+ return -EINVAL;
+ }
+ }
sta_adapter = hdd_get_adapter(hdd_ctx, QDF_STA_MODE);
ucfg_policy_mgr_get_conc_rule1(hdd_ctx->psoc, &conc_rule1);
/*
@@ -5909,7 +5940,10 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
config->RSNWPAReqIE[1] + 2,
config->RSNWPAReqIE);
- if (QDF_STATUS_SUCCESS == status) {
+ if (status != QDF_STATUS_SUCCESS) {
+ ret = -EINVAL;
+ goto error;
+ } else {
/* Now copy over all the security attributes you have
* parsed out. Use the cipher type in the RSN IE
*/
@@ -5958,7 +5992,10 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter,
config->RSNWPAReqIE[1] + 2,
config->RSNWPAReqIE);
- if (QDF_STATUS_SUCCESS == status) {
+ if (status != QDF_STATUS_SUCCESS) {
+ ret = -EINVAL;
+ goto error;
+ } else {
(WLAN_HDD_GET_AP_CTX_PTR(adapter))->
encryption_type = rsn_encrypt_type;
hdd_debug("CSR Encryption: %d mcEncryption: %d num_akm_suites:%d",
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index ad1576d7a9..66d86a076a 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -419,6 +419,7 @@ static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
[QDF_MODULE_ID_GPIO] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_MLO] = {QDF_TRACE_LEVEL_ALL},
[QDF_MODULE_ID_TWT] = {QDF_TRACE_LEVEL_ALL},
+ [QDF_MODULE_ID_COAP] = {QDF_TRACE_LEVEL_ALL},
};
struct notifier_block hdd_netdev_notifier;
@@ -7621,7 +7622,6 @@ static void hdd_init_completion(struct hdd_adapter *adapter)
{
init_completion(&adapter->disconnect_comp_var);
init_completion(&adapter->linkup_event_var);
- init_completion(&adapter->sta_authorized_event);
init_completion(&adapter->offchannel_tx_event);
init_completion(&adapter->tx_action_cnf_event);
init_completion(&adapter->lfr_fw_status.disable_lfr_event);
@@ -9327,6 +9327,19 @@ QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
return status;
}
+void hdd_validate_next_adapter(struct hdd_adapter **curr,
+ struct hdd_adapter **next,
+ wlan_net_dev_ref_dbgid dbg_id)
+{
+ if (!*curr || !*next || *curr != *next)
+ return;
+
+ hdd_err("Validation failed");
+ hdd_adapter_dev_put_debug(*curr, dbg_id);
+ *curr = NULL;
+ *next = NULL;
+}
+
QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
{
struct hdd_context *hdd_ctx;
@@ -15056,6 +15069,7 @@ static int hdd_features_init(struct hdd_context *hdd_ctx)
mac_handle_t mac_handle;
bool b_cts2self, is_imps_enabled;
bool rf_test_mode;
+ bool std_6ghz_conn_policy;
hdd_enter();
@@ -15156,6 +15170,17 @@ static int hdd_features_init(struct hdd_context *hdd_ctx)
wlan_cm_set_6ghz_key_mgmt_mask(hdd_ctx->psoc,
DEFAULT_KEYMGMT_6G_MASK);
}
+
+ status = ucfg_mlme_is_standard_6ghz_conn_policy_enabled(hdd_ctx->psoc,
+ &std_6ghz_conn_policy);
+
+ if (!QDF_IS_STATUS_SUCCESS(status)) {
+ hdd_err("Get 6ghz standard connection policy failed");
+ return QDF_STATUS_E_FAILURE;
+ }
+ if (std_6ghz_conn_policy)
+ wlan_cm_set_standard_6ghz_conn_policy(hdd_ctx->psoc, true);
+
hdd_thermal_stats_cmd_init(hdd_ctx);
sme_set_cal_failure_event_cb(hdd_ctx->mac_handle,
hdd_cal_fail_send_event);
@@ -16631,9 +16656,6 @@ int hdd_register_cb(struct hdd_context *hdd_ctx)
sme_stats_ext2_register_callback(mac_handle,
wlan_hdd_cfg80211_stats_ext2_callback);
- sme_roam_events_register_callback(mac_handle,
- wlan_hdd_cfg80211_roam_events_callback);
-
sme_multi_client_ll_rsp_register_callback(mac_handle,
hdd_latency_level_event_handler_cb);
@@ -16751,7 +16773,6 @@ void hdd_deregister_cb(struct hdd_context *hdd_ctx)
hdd_err("Failed to de-register data stall detect event callback");
hdd_thermal_unregister_callbacks(hdd_ctx);
sme_deregister_oem_data_rsp_callback(mac_handle);
- sme_roam_events_deregister_callback(mac_handle);
sme_multi_client_ll_rsp_deregister_callback(mac_handle);
hdd_exit();
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index 88f353a30a..00766dc954 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -4079,7 +4079,8 @@ roam_rt_stats_fill_cand_info(struct sk_buff *vendor_event, uint8_t idx,
uint8_t i, num_cand = 0;
if (roam_stats->result[idx].present &&
- roam_stats->result[idx].fail_reason) {
+ roam_stats->result[idx].fail_reason &&
+ roam_stats->result[idx].fail_reason != ROAM_FAIL_REASON_UNKNOWN) {
num_cand++;
for (i = 0; i < roam_stats->scan[idx].num_ap; i++) {
if (roam_stats->scan[idx].ap[i].type == 0 &&
@@ -4155,10 +4156,10 @@ roam_rt_stats_fill_cand_info(struct sk_buff *vendor_event, uint8_t idx,
}
void
-wlan_hdd_cfg80211_roam_events_callback(hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats)
+wlan_hdd_cfg80211_roam_events_callback(struct roam_stats_event *roam_stats,
+ uint8_t idx)
{
- struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
+ struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
int status;
uint32_t data_size, roam_event_type = 0;
struct sk_buff *vendor_event;
diff --git a/core/hdd/src/wlan_hdd_stats.h b/core/hdd/src/wlan_hdd_stats.h
index 77acbaf6b4..db6ae5c361 100644
--- a/core/hdd/src/wlan_hdd_stats.h
+++ b/core/hdd/src/wlan_hdd_stats.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -397,21 +397,14 @@ wlan_hdd_cfg80211_stats_ext2_callback(hdd_handle_t hdd_handle,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
* wlan_hdd_cfg80211_roam_events_callback() - roam_events_callback
- * @hdd_handle: opaque handle to the hdd context
- * @idx: TLV index in roam stats event
* @roam_stats: roam events stats
+ * @idx: TLV index in roam stats event
*
* Return: void
*/
void
-wlan_hdd_cfg80211_roam_events_callback(hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats);
-#else
-static inline void
-wlan_hdd_cfg80211_roam_events_callback(hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats)
-{
-}
+wlan_hdd_cfg80211_roam_events_callback(struct roam_stats_event *roam_stats,
+ uint8_t idx);
#endif /* End of WLAN_FEATURE_ROAM_OFFLOAD */
/**
diff --git a/core/hdd/src/wlan_hdd_tsf.c b/core/hdd/src/wlan_hdd_tsf.c
index d2dc413bb8..5e9e5eef9d 100644
--- a/core/hdd/src/wlan_hdd_tsf.c
+++ b/core/hdd/src/wlan_hdd_tsf.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1484,7 +1484,7 @@ static enum hdd_tsf_op_result hdd_tsf_sync_init(struct hdd_adapter *adapter)
}
if (!adapter->enable_dynamic_tsf_sync) {
- hdd_err("TSF sync feature not enabled");
+ hdd_debug("TSF sync feature not enabled");
return HDD_TSF_OP_FAIL;
}
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index 4233e833a6..20310cc7b1 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -32,9 +32,9 @@
#define QWLAN_VERSION_MAJOR 2
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 9
-#define QWLAN_VERSION_EXTRA "A"
+#define QWLAN_VERSION_EXTRA "Y"
#define QWLAN_VERSION_BUILD 17
-#define QWLAN_VERSIONSTR "2.0.9.17A"
+#define QWLAN_VERSIONSTR "2.0.9.17Y"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index 0eeafa8210..a365135113 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -2185,8 +2185,8 @@ void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pBd)
RXMGMT_FLAG_NONE);
break;
default:
- pe_warn("Unhandled public action frame: %x",
- action_hdr->actionID);
+ pe_info_rl("Unhandled public action frame: %x",
+ action_hdr->actionID);
break;
}
break;
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 42f977a23e..f904a43dc2 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -67,6 +67,7 @@
#include "wlan_reg_services_api.h"
#include <lim_mlo.h>
#include <wlan_vdev_mgr_utils_api.h>
+#include "wma_he.h"
/* SME REQ processing function templates */
static bool __lim_process_sme_sys_ready_ind(struct mac_context *, uint32_t *);
@@ -1942,6 +1943,7 @@ lim_handle_11a_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
case MLME_DOT11_MODE_11AC:
/* fallthrough */
case MLME_DOT11_MODE_11AX:
+ case MLME_DOT11_MODE_11BE:
*intersected_mode = MLME_DOT11_MODE_11A;
break;
default:
@@ -1973,6 +1975,7 @@ lim_handle_11b_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
case MLME_DOT11_MODE_11B:
/* fallthrough */
case MLME_DOT11_MODE_11G:
+ case MLME_DOT11_MODE_11BE:
/* Self 11B and BSS 11A cannot connect */
*intersected_mode = MLME_DOT11_MODE_11B;
break;
@@ -2007,6 +2010,7 @@ lim_handle_11g_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
case MLME_DOT11_MODE_11AX:
/* fallthrough */
case MLME_DOT11_MODE_11G:
+ case MLME_DOT11_MODE_11BE:
/* Self 11B and BSS 11A cannot connect */
*intersected_mode = MLME_DOT11_MODE_11G;
break;
@@ -2096,6 +2100,7 @@ lim_handle_11ac_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
*intersected_mode = MLME_DOT11_MODE_11AC;
break;
case MLME_DOT11_MODE_11AX:
+ case MLME_DOT11_MODE_11BE:
if (vht_capable) {
*intersected_mode = MLME_DOT11_MODE_11AC;
break;
@@ -2241,6 +2246,7 @@ lim_handle_11g_only_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
case MLME_DOT11_MODE_11AX:
/* fallthrough */
case MLME_DOT11_MODE_11G:
+ case MLME_DOT11_MODE_11BE:
/* Self 11B and BSS 11A cannot connect */
*intersected_mode = MLME_DOT11_MODE_11G;
break;
@@ -2277,6 +2283,7 @@ lim_handle_11n_only_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
case MLME_DOT11_MODE_11AC:
/* fallthrough */
case MLME_DOT11_MODE_11AX:
+ case MLME_DOT11_MODE_11BE:
if (ie_struct->HTCaps.present) {
*intersected_mode = MLME_DOT11_MODE_11N;
break;
@@ -2322,6 +2329,7 @@ lim_handle_11ac_only_dot11_mode(enum mlme_dot11_mode bss_dot11_mode,
*intersected_mode = MLME_DOT11_MODE_11AC;
break;
case MLME_DOT11_MODE_11AX:
+ case MLME_DOT11_MODE_11BE:
if (vht_capable) {
*intersected_mode = MLME_DOT11_MODE_11AC;
break;
@@ -9222,6 +9230,10 @@ static void obss_color_collision_process_color_change(struct mac_context *mac_ct
pe_debug("New bss color = %d", bss_color_index_array[i]);
he_bss_color.vdev_id = obss_color_info->vdev_id;
he_bss_color.bss_color = bss_color_index_array[i];
+
+ /* Take the wakelock for 2 sec, release it after color change */
+ wma_prevent_suspend_on_obss_color_collision(session->vdev);
+
lim_process_set_he_bss_color(mac_ctx,
(uint32_t *)&he_bss_color);
} else {
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 64a0eb6f7f..1b954d6836 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -55,6 +55,7 @@
#include "wlan_tdls_tgt_api.h"
#include "lim_process_fils.h"
#include "wma.h"
+#include "wma_he.h"
#include <../../core/src/wlan_cm_vdev_api.h>
#include <wlan_mlo_mgr_sta.h>
@@ -2382,6 +2383,8 @@ lim_handle_bss_color_change_ie(struct mac_context *mac_ctx,
lim_send_obss_color_collision_cfg(
mac_ctx, session,
OBSS_COLOR_COLLISION_DETECTION);
+ wma_allow_suspend_after_obss_color_change(
+ session->vdev);
}
lim_send_bss_color_change_ie_update(mac_ctx, session);
}
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 2719c0c1f9..d8275ddc2d 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -682,30 +682,6 @@ QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle,
*/
QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t vdev_id,
struct wlan_crypto_pmksa *pmk_cache);
-
-/**
- * sme_roam_events_register_callback() - Register roam events callback
- * @mac_handle: Opaque handle to the MAC context
- * @roam_rt_stats_cb: Function to be invoked for roam events stats
- *
- * This function will register a callback for roams events stats.
- *
- * Return: void
- */
-void sme_roam_events_register_callback(mac_handle_t mac_handle,
- void (*roam_rt_stats_cb)(
- hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats));
-
-/**
- * sme_roam_events_deregister_callback() - DeRegister roam events callback
- * @mac_handle: Opaque handle to the MAC context
- *
- * This function will deregister the callback of roams events stats.
- *
- * Return: void
- */
-void sme_roam_events_deregister_callback(mac_handle_t mac_handle);
#else
static inline
void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
@@ -741,16 +717,6 @@ QDF_STATUS sme_set_pmk_cache_ft(mac_handle_t mac_handle, uint8_t vdev_id,
return QDF_STATUS_SUCCESS;
}
-static inline void
-sme_roam_events_register_callback(mac_handle_t mac_handle,
- void (*roam_rt_stats_cb)(
- hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats))
-{}
-
-static inline
-void sme_roam_events_deregister_callback(mac_handle_t mac_handle)
-{}
#endif
QDF_STATUS sme_get_config_param(mac_handle_t mac_handle,
@@ -1938,9 +1904,7 @@ QDF_STATUS sme_nss_update_request(uint32_t vdev_id,
uint32_t original_vdev_id,
uint32_t request_id);
-typedef void (*sme_peer_authorized_fp) (uint32_t vdev_id);
QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
- sme_peer_authorized_fp auth_fp,
uint32_t vdev_id);
QDF_STATUS sme_soc_set_dual_mac_config(struct policy_mgr_dual_mac_config msg);
QDF_STATUS sme_soc_set_antenna_mode(mac_handle_t mac_handle,
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 6fcd1c6a60..2187e79553 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -521,10 +521,6 @@ struct sme_context {
#if defined(CLD_PM_QOS) && defined(WLAN_FEATURE_LL_MODE)
void (*beacon_latency_event_cb)(uint32_t latency_level);
#endif
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
- void (*roam_rt_stats_cb)(hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats);
-#endif
};
#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index 3011fb59d3..634781b492 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -12068,13 +12068,11 @@ QDF_STATUS sme_soc_set_antenna_mode(mac_handle_t mac_handle,
/**
* sme_set_peer_authorized() - call peer authorized callback
* @peer_addr: peer mac address
- * @auth_cb: auth callback
* @vdev_id: vdev id
*
* Return: QDF Status
*/
QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
- sme_peer_authorized_fp auth_cb,
uint32_t vdev_id)
{
void *wma_handle;
@@ -12083,7 +12081,6 @@ QDF_STATUS sme_set_peer_authorized(uint8_t *peer_addr,
if (!wma_handle)
return QDF_STATUS_E_FAILURE;
- wma_set_peer_authorized_cb(wma_handle, auth_cb);
return wma_set_peer_param(wma_handle, peer_addr, WMI_PEER_AUTHORIZE,
1, vdev_id);
}
@@ -15200,6 +15197,24 @@ sme_get_roam_scan_stats(mac_handle_t mac_handle,
return status;
}
+#ifdef WLAN_FEATURE_11BE
+static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode)
+{
+ if (phy_mode == eCSR_DOT11_MODE_AUTO ||
+ CSR_IS_DOT11_PHY_MODE_11BE(phy_mode) ||
+ CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phy_mode)) {
+ return true;
+ }
+
+ return false;
+}
+#else
+static inline bool sme_is_phy_mode_11be(eCsrPhyMode phy_mode)
+{
+ return false;
+}
+#endif
+
void sme_update_score_config(mac_handle_t mac_handle, eCsrPhyMode phy_mode,
uint8_t num_rf_chains)
{
@@ -15217,15 +15232,13 @@ void sme_update_score_config(mac_handle_t mac_handle, eCsrPhyMode phy_mode,
config.vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
config.vdev_nss_5g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
-#ifdef WLAN_FEATURE_11BE
- if (phy_mode == eCSR_DOT11_MODE_AUTO ||
- CSR_IS_DOT11_PHY_MODE_11BE(phy_mode) ||
- CSR_IS_DOT11_PHY_MODE_11BE_ONLY(phy_mode)) {
+
+ if (sme_is_phy_mode_11be(phy_mode))
config.eht_cap = 1;
- config.he_cap = 1;
- }
-#endif
- if (phy_mode == eCSR_DOT11_MODE_11ax ||
+
+ if (config.eht_cap ||
+ phy_mode == eCSR_DOT11_MODE_AUTO ||
+ phy_mode == eCSR_DOT11_MODE_11ax ||
phy_mode == eCSR_DOT11_MODE_11ax_ONLY)
config.he_cap = 1;
@@ -16262,25 +16275,4 @@ p2p_self_peer_create:
}
#endif
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-void sme_roam_events_register_callback(mac_handle_t mac_handle,
- void (*roam_rt_stats_cb)(
- hdd_handle_t hdd_handle, uint8_t idx,
- struct roam_stats_event *roam_stats))
-{
- struct mac_context *mac = MAC_CONTEXT(mac_handle);
-
- if (!mac) {
- sme_err("Invalid mac context");
- return;
- }
-
- mac->sme.roam_rt_stats_cb = roam_rt_stats_cb;
-}
-
-void sme_roam_events_deregister_callback(mac_handle_t mac_handle)
-{
- sme_roam_events_register_callback(mac_handle, NULL);
-}
-#endif
diff --git a/core/sme/src/qos/sme_qos.c b/core/sme/src/qos/sme_qos.c
index 21e161abb6..b4025f5685 100644
--- a/core/sme/src/qos/sme_qos.c
+++ b/core/sme/src/qos/sme_qos.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -3351,8 +3351,7 @@ static QDF_STATUS sme_qos_process_ft_reassoc_req_ev(
*/
entry = csr_ll_peek_head(&sme_qos_cb.flow_list, false);
if (!entry) {
- QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_WARN,
- FL("Flow List empty, nothing to update"));
+ sme_debug("Flow List empty, nothing to update");
return QDF_STATUS_E_FAILURE;
}
@@ -4680,9 +4679,7 @@ static QDF_STATUS sme_qos_process_reassoc_success_ev(struct mac_context *mac_ctx
mac_ctx, sessionid,
event_info);
} else {
- QDF_TRACE(QDF_MODULE_ID_SME,
- QDF_TRACE_LEVEL_ERROR, FL(
- "session or RIC data is not present"));
+ sme_debug("session or RIC data is not present");
}
}
#ifdef FEATURE_WLAN_ESE
diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h
index bf2a48036f..e5017c2c9c 100644
--- a/core/wma/inc/wma.h
+++ b/core/wma/inc/wma.h
@@ -854,7 +854,6 @@ struct wma_wlm_stats_data {
* @log_completion_timer: log completion timer
* @old_hw_mode_index: Previous configured HW mode index
* @new_hw_mode_index: Current configured HW mode index
- * @peer_authorized_cb: peer authorized hdd callback
* @ocb_config_req: OCB request context
* @self_gen_frm_pwr: Self-generated frame power
* @tx_chain_mask_cck: Is the CCK tx chain mask enabled
@@ -981,7 +980,6 @@ typedef struct {
qdf_mc_timer_t log_completion_timer;
uint32_t old_hw_mode_index;
uint32_t new_hw_mode_index;
- wma_peer_authorized_fp peer_authorized_cb;
struct sir_ocb_config *ocb_config_req;
uint16_t self_gen_frm_pwr;
bool tx_chain_mask_cck;
diff --git a/core/wma/inc/wma_api.h b/core/wma/inc/wma_api.h
index 44f5c69a4e..38283b688e 100644
--- a/core/wma/inc/wma_api.h
+++ b/core/wma/inc/wma_api.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -174,7 +174,6 @@ void wma_get_phy_mode_cb(qdf_freq_t freq, uint32_t chan_width,
QDF_STATUS wma_set_htconfig(uint8_t vdev_id, uint16_t ht_capab, int value);
-void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb);
QDF_STATUS wma_set_peer_param(void *wma_ctx, uint8_t *peer_addr,
uint32_t param_id,
uint32_t param_value, uint32_t vdev_id);
diff --git a/core/wma/inc/wma_he.h b/core/wma/inc/wma_he.h
index c01233d282..602b1ff2b2 100644
--- a/core/wma/inc/wma_he.h
+++ b/core/wma/inc/wma_he.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -243,6 +244,23 @@ void wma_set_he_vdev_param(struct wma_txrx_node *intr, WMI_VDEV_PARAM param_id,
uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
WMI_VDEV_PARAM param_id);
+/**
+ * wma_prevent_suspend_on_obss_color_collision() - prevent suspend on obss color
+ * collision
+ * @vdev: pointer to vdev object
+ *
+ * Return: none
+ */
+void wma_prevent_suspend_on_obss_color_collision(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wma_allow_suspend_after_obss_color_change() - allow suspend on obss color
+ * change
+ * @vdev: pointer to vdev object
+ *
+ * Return: none
+ */
+void wma_allow_suspend_after_obss_color_change(struct wlan_objmgr_vdev *vdev);
#else
static inline void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
{
@@ -333,6 +351,15 @@ static inline uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
return 0;
}
+static inline void wma_prevent_suspend_on_obss_color_collision(
+ struct wlan_objmgr_vdev *vdev)
+{
+}
+
+static inline void wma_allow_suspend_after_obss_color_change(
+ struct wlan_objmgr_vdev *vdev)
+{
+}
#endif
#endif /* __WMA_HE_H */
diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h
index 9097479276..23e20da465 100644
--- a/core/wma/inc/wma_internal.h
+++ b/core/wma/inc/wma_internal.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -962,10 +962,6 @@ int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params);
*/
QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value);
-int wma_peer_state_change_event_handler(void *handle,
- uint8_t *event_buff,
- uint32_t len);
-
QDF_STATUS wma_set_enable_disable_mcc_adaptive_scheduler(uint32_t
mcc_adaptive_scheduler);
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 039164579a..220d1e3508 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1073,57 +1073,6 @@ QDF_STATUS wma_check_txrx_chainmask(int num_rf_chains, int cmd_value)
}
/**
- * wma_peer_state_change_event_handler() - peer state change event handler
- * @handle: wma handle
- * @event_buff: event buffer
- * @len: length of buffer
- *
- * This event handler unpauses vdev if peer state change to AUTHORIZED STATE
- *
- * Return: 0 for success or error code
- */
-int wma_peer_state_change_event_handler(void *handle,
- uint8_t *event_buff,
- uint32_t len)
-{
- WMI_PEER_STATE_EVENTID_param_tlvs *param_buf;
- wmi_peer_state_event_fixed_param *event;
-#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
- tp_wma_handle wma_handle = (tp_wma_handle) handle;
-#endif
-
- if (!event_buff) {
- wma_err("Received NULL event ptr from FW");
- return -EINVAL;
- }
- param_buf = (WMI_PEER_STATE_EVENTID_param_tlvs *) event_buff;
- if (!param_buf) {
- wma_err("Received NULL buf ptr from FW");
- return -ENOMEM;
- }
-
- event = param_buf->fixed_param;
-
- if ((cdp_get_opmode(cds_get_context(QDF_MODULE_ID_SOC),
- event->vdev_id) == wlan_op_mode_sta) &&
- event->state == WMI_PEER_STATE_AUTHORIZED) {
- /*
- * set event so that hdd
- * can procced and unpause tx queue
- */
-#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
- if (!wma_handle->peer_authorized_cb) {
- wma_err("peer authorized cb not registered");
- return -EINVAL;
- }
- wma_handle->peer_authorized_cb(event->vdev_id);
-#endif
- }
-
- return 0;
-}
-
-/**
* wma_set_enable_disable_mcc_adaptive_scheduler() -enable/disable mcc scheduler
* @mcc_adaptive_scheduler: enable/disable
*
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index eca4b08e29..e2a1610c62 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -1412,20 +1412,6 @@ wma_vdev_set_param(wmi_unified_t wmi_handle, uint32_t if_id,
}
/**
- * wma_set_peer_authorized_cb() - set peer authorized callback function
- * @wma_ctx: wma handle
- * @auth_cb: peer authorized callback
- *
- * Return: none
- */
-void wma_set_peer_authorized_cb(void *wma_ctx, wma_peer_authorized_fp auth_cb)
-{
- tp_wma_handle wma_handle = (tp_wma_handle) wma_ctx;
-
- wma_handle->peer_authorized_cb = auth_cb;
-}
-
-/**
* wma_set_peer_param() - set peer parameter in fw
* @wma_ctx: wma handle
* @peer_addr: peer mac address
diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c
index 8fb8254798..44f82f6483 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -2910,6 +2910,11 @@ wma_wow_wakeup_host_trigger_ssr(t_wma_handle *wma, uint32_t reason)
if (!wlan_pmo_enable_ssr_on_page_fault(wma->psoc))
return;
+ if (wmi_get_runtime_pm_inprogress(wma->wmi_handle)) {
+ wma_debug("Ignore run time pm wakeup");
+ return;
+ }
+
pagefault_wakeups_for_ssr =
wlan_pmo_get_max_pagefault_wakeups_for_ssr(wma->psoc);
diff --git a/core/wma/src/wma_he.c b/core/wma/src/wma_he.c
index 0e22736842..37f181f421 100644
--- a/core/wma/src/wma_he.c
+++ b/core/wma/src/wma_he.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -1523,3 +1523,30 @@ uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
}
return 0;
}
+
+void wma_prevent_suspend_on_obss_color_collision(struct wlan_objmgr_vdev *vdev)
+{
+ struct mlme_legacy_priv *mlme_priv;
+
+ mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+ if (!mlme_priv)
+ return;
+
+ qdf_wake_lock_timeout_acquire(&mlme_priv->bss_color_change_wakelock,
+ MAX_WAKELOCK_FOR_BSS_COLOR_CHANGE);
+ qdf_runtime_pm_prevent_suspend(
+ &mlme_priv->bss_color_change_runtime_lock);
+}
+
+void wma_allow_suspend_after_obss_color_change(struct wlan_objmgr_vdev *vdev)
+{
+ struct mlme_legacy_priv *mlme_priv;
+
+ mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+ if (!mlme_priv)
+ return;
+
+ qdf_runtime_pm_allow_suspend(
+ &mlme_priv->bss_color_change_runtime_lock);
+ qdf_wake_lock_release(&mlme_priv->bss_color_change_wakelock, 0);
+}
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 2e860b466d..7426c8f646 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -3340,12 +3340,6 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
WMA_RX_SERIALIZER_CTX);
#endif /* FEATURE_OEM_DATA_SUPPORT */
- /* Register peer change event handler */
- wmi_unified_register_event_handler(wma_handle->wmi_handle,
- wmi_peer_state_event_id,
- wma_peer_state_change_event_handler,
- WMA_RX_WORK_CTX);
-
/* Register beacon tx complete event id. The event is required
* for sending channel switch announcement frames
*/
diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c
index fb6cc155d6..09ff31987c 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -3798,13 +3798,12 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
mgmt_rx_params = qdf_mem_malloc(sizeof(*mgmt_rx_params));
if (!mgmt_rx_params) {
- wma_err("memory allocation failed");
return -ENOMEM;
}
if (wmi_extract_mgmt_rx_params(wma_handle->wmi_handle,
data, mgmt_rx_params, &bufp) != QDF_STATUS_SUCCESS) {
- wma_err("Extraction of mgmt rx params failed");
+ wma_err_rl("Extraction of mgmt rx params failed");
qdf_mem_free(mgmt_rx_params);
return -EINVAL;
}
@@ -3812,8 +3811,8 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
if (mgmt_rx_params->buf_len > data_len ||
!mgmt_rx_params->buf_len ||
!bufp) {
- wma_err("Invalid data_len %u, buf_len %u bufp %pK",
- data_len, mgmt_rx_params->buf_len, bufp);
+ wma_err_rl("Invalid data_len %u, buf_len %u bufp %pK",
+ data_len, mgmt_rx_params->buf_len, bufp);
qdf_mem_free(mgmt_rx_params);
return -EINVAL;
}
diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c
index 65a358fe6e..18636d5b89 100644
--- a/core/wma/src/wma_scan_roam.c
+++ b/core/wma/src/wma_scan_roam.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -2607,7 +2607,8 @@ void wma_handle_roam_sync_timeout(tp_wma_handle wma_handle,
CM_ROAM_NOTIF_ROAM_ABORT);
}
-void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif)
+void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif,
+ uint32_t reason)
{
tp_wma_handle wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
@@ -2621,7 +2622,7 @@ void cm_invalid_roam_reason_handler(uint32_t vdev_id, enum cm_roam_notif notif)
notif == CM_ROAM_NOTIF_SCAN_END)
cm_report_roam_rt_stats(wma_handle->psoc, vdev_id,
ROAM_RT_STATS_TYPE_SCAN_STATE,
- NULL, notif, 0);
+ NULL, notif, 0, reason);
}
#endif
@@ -2786,7 +2787,7 @@ cm_handle_roam_reason_invoke_roam_fail(uint8_t vdev_id, uint32_t notif_params,
notif_params);
cm_report_roam_rt_stats(wma_handle->psoc, vdev_id,
ROAM_RT_STATS_TYPE_INVOKE_FAIL_REASON,
- NULL, notif_params, 0);
+ NULL, notif_params, 0, 0);
}
void
diff --git a/os_if/coap/inc/wlan_cfg80211_coap.h b/os_if/coap/inc/wlan_cfg80211_coap.h
new file mode 100644
index 0000000000..3803efc490
--- /dev/null
+++ b/os_if/coap/inc/wlan_cfg80211_coap.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: declares driver functions interfacing with linux kernel
+ */
+
+#ifndef _WLAN_CFG80211_COAP_H_
+#define _WLAN_CFG80211_COAP_H_
+#include <wlan_objmgr_vdev_obj.h>
+
+#ifdef WLAN_FEATURE_COAP
+/**
+ * wlan_cfg80211_coap_offload() - configure CoAP offloading
+ * @wiphy: pointer to wireless wiphy structure.
+ * @vdev: VDEV Object pointer
+ * @data: pointer to netlink TLV buffer
+ * @data_len: the length of @data in bytes
+ *
+ * Return: An error code or 0 on success.
+ */
+int
+wlan_cfg80211_coap_offload(struct wiphy *wiphy, struct wlan_objmgr_vdev *vdev,
+ const void *data, int data_len);
+#endif
+#endif
diff --git a/os_if/coap/src/wlan_cfg80211_coap.c b/os_if/coap/src/wlan_cfg80211_coap.c
new file mode 100644
index 0000000000..30ce696ed2
--- /dev/null
+++ b/os_if/coap/src/wlan_cfg80211_coap.c
@@ -0,0 +1,683 @@
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: defines driver functions interfacing with linux kernel
+ */
+#include <wmi_unified_param.h>
+#include <wlan_osif_request_manager.h>
+#include <osif_sync.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_hdd_main.h>
+#include <wlan_coap_main.h>
+#include <wlan_coap_ucfg_api.h>
+#include <wlan_cfg80211_coap.h>
+
+#define COAP_MATCH_DATA_BYTES_MAX 16
+#define COAP_MSG_BYTES_MAX 1152
+#define COAP_OFFLOAD_REPLY_CACHE_EXPTIME_MS 40000
+#define COAP_OFFLOAD_CACHE_GET_TIMEOUT_MS 2000
+
+#define COAP_ATTR(_name) QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_ ## _name
+
+static const struct nla_policy
+coap_offload_filter_policy[COAP_ATTR(FILTER_MAX) + 1] = {
+ [COAP_ATTR(FILTER_DEST_IPV4)] = {.type = NLA_U32},
+ [COAP_ATTR(FILTER_DEST_IPV4_IS_BC)] = {.type = NLA_FLAG},
+ [COAP_ATTR(FILTER_DEST_PORT)] = {.type = NLA_U16},
+ [COAP_ATTR(FILTER_MATCH_OFFSET)] = {.type = NLA_U32},
+ [COAP_ATTR(FILTER_MATCH_DATA)] = {
+ .type = NLA_BINARY, .len = COAP_MATCH_DATA_BYTES_MAX},
+};
+
+static const struct nla_policy
+coap_offload_tx_ipv4_policy[COAP_ATTR(TX_IPV4_MAX) + 1] = {
+ [COAP_ATTR(TX_IPV4_SRC_ADDR)] = {.type = NLA_U32},
+ [COAP_ATTR(TX_IPV4_SRC_PORT)] = {.type = NLA_U16},
+ [COAP_ATTR(TX_IPV4_DEST_ADDR)] = {.type = NLA_U32},
+ [COAP_ATTR(TX_IPV4_DEST_IS_BC)] = {.type = NLA_FLAG},
+ [COAP_ATTR(TX_IPV4_DEST_PORT)] = {.type = NLA_U16},
+};
+
+static const struct nla_policy
+coap_offload_reply_policy[COAP_ATTR(REPLY_MAX) + 1] = {
+ [COAP_ATTR(REPLY_SRC_IPV4)] = {.type = NLA_U32},
+ [COAP_ATTR(REPLY_FILTER)] =
+ VENDOR_NLA_POLICY_NESTED(coap_offload_filter_policy),
+ [COAP_ATTR(REPLY_MSG)] = {
+ .type = NLA_BINARY, .len = COAP_MSG_BYTES_MAX},
+ [COAP_ATTR(REPLY_CACHE_EXPTIME)] = {.type = NLA_U32},
+};
+
+static const struct nla_policy
+coap_offload_periodic_tx_policy[COAP_ATTR(PERIODIC_TX_MAX) + 1] = {
+ [COAP_ATTR(PERIODIC_TX_IPV4)] =
+ VENDOR_NLA_POLICY_NESTED(coap_offload_tx_ipv4_policy),
+ [COAP_ATTR(PERIODIC_TX_PERIOD)] = {.type = NLA_U32},
+ [COAP_ATTR(PERIODIC_TX_MSG)] = {
+ .type = NLA_BINARY, .len = COAP_MSG_BYTES_MAX},
+};
+
+const struct nla_policy
+coap_offload_policy[COAP_ATTR(MAX) + 1] = {
+ [COAP_ATTR(ACTION)] = {.type = NLA_U32 },
+ [COAP_ATTR(REQ_ID)] = {.type = NLA_U32 },
+ [COAP_ATTR(REPLY)] =
+ VENDOR_NLA_POLICY_NESTED(coap_offload_reply_policy),
+ [COAP_ATTR(PERIODIC_TX)] =
+ VENDOR_NLA_POLICY_NESTED(coap_offload_periodic_tx_policy),
+};
+
+/**
+ * wlan_cfg80211_coap_offload_reply_fill_filter() - fill filter for CoAP
+ * offload reply.
+ * @attr_filter: pointer to filter attribute
+ * @params: pointer to parameters for CoAP offload reply
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_reply_fill_filter(struct nlattr *attr_filter,
+ struct coap_offload_reply_param *params)
+{
+ struct nlattr *tb[COAP_ATTR(FILTER_MAX) + 1];
+
+ if (!attr_filter) {
+ coap_err("No ATTR filter");
+ return -EINVAL;
+ }
+
+ if (!nla_data(attr_filter)) {
+ coap_err("Invalid filter");
+ return -EINVAL;
+ }
+
+ if (wlan_cfg80211_nla_parse_nested(tb, COAP_ATTR(FILTER_MAX),
+ attr_filter,
+ coap_offload_filter_policy)) {
+ coap_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ if (!tb[COAP_ATTR(FILTER_DEST_IPV4)]) {
+ coap_err("no ATTR dest IPv4");
+ return -EINVAL;
+ }
+
+ params->dest_ip_v4 = nla_get_u32(tb[COAP_ATTR(FILTER_DEST_IPV4)]);
+ params->dest_ip_v4_is_bc =
+ nla_get_flag(tb[COAP_ATTR(FILTER_DEST_IPV4_IS_BC)]);
+
+ if (!tb[COAP_ATTR(FILTER_DEST_PORT)]) {
+ coap_err("no ATTR dest IPv4 port");
+ return -EINVAL;
+ }
+
+ params->dest_udp_port = nla_get_u16(tb[COAP_ATTR(FILTER_DEST_PORT)]);
+
+ if (!tb[COAP_ATTR(FILTER_MATCH_OFFSET)]) {
+ coap_err("no ATTR match offset");
+ return -EINVAL;
+ }
+
+ params->verify_offset =
+ nla_get_u32(tb[COAP_ATTR(FILTER_MATCH_OFFSET)]);
+
+ if (!tb[COAP_ATTR(FILTER_MATCH_DATA)]) {
+ coap_err("no ATTR match data");
+ return -EINVAL;
+ }
+
+ params->verify_len = nla_len(tb[COAP_ATTR(FILTER_MATCH_DATA)]);
+ if (!params->verify_len) {
+ coap_err("invalid match data len");
+ return -EINVAL;
+ }
+
+ params->verify = nla_data(tb[COAP_ATTR(FILTER_MATCH_DATA)]);
+ return 0;
+}
+
+/**
+ * wlan_cfg80211_coap_offload_reply_enable() - enable CoAP offload reply
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @attr_reply: pointer to CoAP offload reply attribute
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_reply_enable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id,
+ struct nlattr *attr_reply)
+{
+ struct nlattr *tb[COAP_ATTR(REPLY_MAX) + 1];
+ struct coap_offload_reply_param params = {0};
+ struct nlattr *attr;
+ QDF_STATUS status;
+ int ret;
+
+ if (!attr_reply) {
+ coap_err("No ATTR reply");
+ return -EINVAL;
+ }
+
+ if (wlan_cfg80211_nla_parse_nested(tb, COAP_ATTR(REPLY_MAX),
+ attr_reply,
+ coap_offload_reply_policy)) {
+ coap_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ attr = tb[COAP_ATTR(REPLY_SRC_IPV4)];
+ if (!attr) {
+ coap_err("No ATTR IPv4");
+ return -EINVAL;
+ }
+
+ params.pattern_id = req_id;
+ params.vdev_id = wlan_vdev_get_id(vdev);
+ params.src_ip_v4 = nla_get_u32(attr);
+
+ attr = tb[COAP_ATTR(REPLY_FILTER)];
+ ret = wlan_cfg80211_coap_offload_reply_fill_filter(attr, &params);
+ if (ret)
+ return ret;
+
+ attr = tb[COAP_ATTR(REPLY_MSG)];
+ if (!attr) {
+ coap_err("No ATTR msg");
+ return -EINVAL;
+ }
+
+ params.coapmsg_len = nla_len(attr);
+ params.coapmsg = nla_data(attr);
+
+ attr = tb[COAP_ATTR(REPLY_CACHE_EXPTIME)];
+ if (!attr)
+ params.cache_timeout = COAP_OFFLOAD_REPLY_CACHE_EXPTIME_MS;
+ else
+ params.cache_timeout = nla_get_u32(attr);
+
+ status = ucfg_coap_offload_reply_enable(vdev, &params);
+ ret = qdf_status_to_os_return(status);
+ return ret;
+}
+
+/**
+ * wlan_cfg80211_coap_offload_fill_tx_ipv4() - fill IPv4 source/destination
+ * address/port for offload transmitting.
+ * @attr_ipv4: pointer to TX IPv4 attribute
+ * @params: pointer to parameters for CoAP offload reply
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_fill_tx_ipv4(struct nlattr *attr_ipv4,
+ struct coap_offload_periodic_tx_param *params)
+{
+ struct nlattr *tb[COAP_ATTR(TX_IPV4_MAX) + 1];
+
+ if (!attr_ipv4) {
+ coap_err("No ATTR TX IPv4");
+ return -EINVAL;
+ }
+
+ if (wlan_cfg80211_nla_parse_nested(tb, COAP_ATTR(TX_IPV4_MAX),
+ attr_ipv4,
+ coap_offload_tx_ipv4_policy)) {
+ coap_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ if (!tb[COAP_ATTR(TX_IPV4_SRC_ADDR)]) {
+ coap_err("no ATTR src addr");
+ return -EINVAL;
+ }
+
+ params->src_ip_v4 = nla_get_u32(tb[COAP_ATTR(TX_IPV4_SRC_ADDR)]);
+ if (tb[COAP_ATTR(TX_IPV4_SRC_PORT)])
+ params->src_udp_port =
+ nla_get_u32(tb[COAP_ATTR(TX_IPV4_SRC_PORT)]);
+
+ if (!tb[COAP_ATTR(TX_IPV4_DEST_ADDR)]) {
+ coap_err("no ATTR IPv4 dest addr");
+ return -EINVAL;
+ }
+
+ params->dest_ip_v4 = nla_get_u32(tb[COAP_ATTR(TX_IPV4_DEST_ADDR)]);
+ params->dest_ip_v4_is_bc =
+ nla_get_flag(tb[COAP_ATTR(TX_IPV4_DEST_IS_BC)]);
+
+ if (!tb[COAP_ATTR(TX_IPV4_DEST_PORT)]) {
+ coap_err("no ATTR dest IPv4 port");
+ return -EINVAL;
+ }
+
+ params->dest_udp_port =
+ nla_get_u32(tb[COAP_ATTR(TX_IPV4_DEST_PORT)]);
+ return 0;
+}
+
+/**
+ * wlan_cfg80211_coap_offload_periodic_tx_enable() - enable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ * @attr_reply: pointer to CoAP offload periodic TX attribute
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_periodic_tx_enable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id,
+ struct nlattr *attr_periodic_tx)
+{
+ struct nlattr *tb[COAP_ATTR(PERIODIC_TX_MAX) + 1];
+ struct coap_offload_periodic_tx_param param = {0};
+ struct nlattr *attr_ipv4;
+ QDF_STATUS status;
+ int ret;
+
+ if (!attr_periodic_tx) {
+ coap_err("No ATTR periodic tx");
+ return -EINVAL;
+ }
+
+ if (wlan_cfg80211_nla_parse_nested(tb, COAP_ATTR(PERIODIC_TX_MAX),
+ attr_periodic_tx,
+ coap_offload_periodic_tx_policy)) {
+ coap_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ if (!tb[COAP_ATTR(PERIODIC_TX_PERIOD)]) {
+ coap_err("no ATTR period");
+ return -EINVAL;
+ }
+
+ param.timeout = nla_get_u32(tb[COAP_ATTR(PERIODIC_TX_PERIOD)]);
+ attr_ipv4 = tb[COAP_ATTR(PERIODIC_TX_IPV4)];
+ ret = wlan_cfg80211_coap_offload_fill_tx_ipv4(attr_ipv4, &param);
+ if (ret)
+ return ret;
+
+ param.vdev_id = wlan_vdev_get_id(vdev);
+ param.pattern_id = req_id;
+ if (!tb[COAP_ATTR(PERIODIC_TX_MSG)]) {
+ coap_err("no ATTR msg");
+ return -EINVAL;
+ }
+
+ param.coapmsg_len = nla_len(tb[COAP_ATTR(PERIODIC_TX_MSG)]);
+ param.coapmsg = nla_data(tb[COAP_ATTR(PERIODIC_TX_MSG)]);
+ status = ucfg_coap_offload_periodic_tx_enable(vdev, &param);
+ return qdf_status_to_os_return(status);
+}
+
+/**
+ * wlan_cfg80211_coap_offload_periodic_tx_enable() - disable CoAP offload
+ * periodic transmitting
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_periodic_tx_disable(struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ QDF_STATUS status;
+
+ status = ucfg_coap_offload_periodic_tx_disable(vdev, req_id);
+ return qdf_status_to_os_return(status);
+}
+
+/**
+ * wlan_cfg80211_dealloc_coap_buf_info() - Callback to free priv
+ * allocations for CoAP buffer info
+ * @priv: Pointer to priv data statucture
+ *
+ * Return: None
+ */
+static void wlan_cfg80211_dealloc_coap_buf_info(void *priv)
+{
+ struct coap_buf_info *info = priv;
+ struct coap_buf_node *cur, *next;
+
+ if (!info)
+ return;
+
+ qdf_list_for_each_del(&info->info_list, cur, next, node) {
+ qdf_list_remove_node(&info->info_list, &cur->node);
+ qdf_mem_free(cur->payload);
+ qdf_mem_free(cur);
+ }
+
+ qdf_list_destroy(&info->info_list);
+}
+
+static void
+wlan_cfg80211_coap_cache_get_cbk(void *context, struct coap_buf_info *info)
+{
+ struct osif_request *request;
+ struct coap_buf_info *priv_info;
+
+ if (!context || !info)
+ return;
+
+ request = osif_request_get(context);
+ if (!request)
+ return;
+
+ priv_info = osif_request_priv(request);
+ if (info->req_id == priv_info->req_id) {
+ qdf_list_join(&priv_info->info_list, &info->info_list);
+ if (!info->more_info)
+ osif_request_complete(request);
+ }
+
+ osif_request_put(request);
+}
+
+/**
+ * wlan_cfg80211_coap_fill_buf_info() - Fill cache get response buffer
+ * @reply_skb : pointer to reply_skb
+ * @info : information of cached CoAP messages
+ * @index : attribute type index for nla_next_start()
+ *
+ * Return : 0 on success and errno on failure
+ */
+static int
+wlan_cfg80211_coap_fill_buf_info(struct sk_buff *reply_skb,
+ struct coap_buf_node *info, int index)
+{
+ struct nlattr *attr;
+
+ attr = nla_nest_start(reply_skb, index);
+ if (!attr) {
+ coap_err("nla_nest_start failed");
+ return -EINVAL;
+ }
+
+ if (hdd_wlan_nla_put_u64(reply_skb, COAP_ATTR(CACHE_INFO_TS),
+ info->tsf) ||
+ nla_put_u32(reply_skb, COAP_ATTR(CACHE_INFO_SRC_IPV4),
+ info->src_ip) ||
+ nla_put(reply_skb, COAP_ATTR(CACHE_INFO_MSG),
+ info->len, info->payload)) {
+ coap_err("nla_put failed");
+ return -EINVAL;
+ }
+
+ nla_nest_end(reply_skb, attr);
+ return 0;
+}
+
+/**
+ * wlan_cfg80211_coap_offload_cache_deliver() - deliver cached CoAP messages
+ * @wiphy: pointer to wireless wiphy structure.
+ * @cache_list: list of cached CoAP messages
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_cache_deliver(struct wiphy *wiphy,
+ qdf_list_t *cache_list)
+{
+ struct sk_buff *skb;
+ uint32_t skb_len = NLMSG_HDRLEN;
+ struct coap_buf_node *cur, *next;
+ struct nlattr *attr;
+ int i = 0, ret;
+
+ /* QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHES */
+ skb_len += nla_total_size(0);
+ qdf_list_for_each_del(cache_list, cur, next, node) {
+ if (!cur->len || !cur->payload)
+ continue;
+
+ /* nest attribute */
+ skb_len += nla_total_size(0);
+
+ /* QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_TS */
+ skb_len += nla_total_size(sizeof(uint64_t));
+
+ /* QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_SRC_IPV4 */
+ skb_len += nla_total_size(sizeof(uint32_t));
+
+ /* QCA_WLAN_VENDOR_ATTR_COAP_OFFLOAD_CACHE_INFO_MSG */
+ skb_len += nla_total_size(cur->len);
+ }
+
+ skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);
+ attr = nla_nest_start(skb, COAP_ATTR(CACHES));
+ if (!attr) {
+ hdd_err("nla_nest_start failed");
+ wlan_cfg80211_vendor_free_skb(skb);
+ return -EINVAL;
+ }
+
+ qdf_list_for_each_del(cache_list, cur, next, node) {
+ if (!cur->len || !cur->payload)
+ continue;
+
+ qdf_list_remove_node(cache_list, &cur->node);
+ ret = wlan_cfg80211_coap_fill_buf_info(skb, cur, i++);
+ if (ret) {
+ wlan_cfg80211_vendor_free_skb(skb);
+ return -EINVAL;
+ }
+
+ qdf_mem_free(cur->payload);
+ qdf_mem_free(cur);
+ }
+
+ nla_nest_end(skb, attr);
+ return wlan_cfg80211_vendor_cmd_reply(skb);
+}
+
+/**
+ * wlan_cfg80211_coap_offload_cache_get() - get cached CoAP messages
+ * @wiphy: pointer to wireless wiphy structure.
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_cache_get(struct wiphy *wiphy,
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ void *cookie;
+ QDF_STATUS status;
+ struct osif_request *request;
+ struct coap_buf_info *buf_info;
+ int ret;
+ static const struct osif_request_params params = {
+ .priv_size = sizeof(*buf_info),
+ .timeout_ms = COAP_OFFLOAD_CACHE_GET_TIMEOUT_MS,
+ .dealloc = wlan_cfg80211_dealloc_coap_buf_info,
+ };
+
+ request = osif_request_alloc(&params);
+ if (!request) {
+ coap_err("Request allocation failure");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ buf_info = osif_request_priv(request);
+ qdf_list_create(&buf_info->info_list, 0);
+ buf_info->req_id = req_id;
+ buf_info->vdev_id = wlan_vdev_get_id(vdev);
+
+ cookie = osif_request_cookie(request);
+ status = ucfg_coap_offload_cache_get(vdev, req_id,
+ wlan_cfg80211_coap_cache_get_cbk,
+ cookie);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ coap_err("Unable to get cache");
+ goto out;
+ }
+
+ ret = osif_request_wait_for_response(request);
+ if (ret) {
+ coap_err("Target response timed out");
+ status = qdf_status_from_os_return(ret);
+ goto out;
+ }
+
+ ret = wlan_cfg80211_coap_offload_cache_deliver(wiphy,
+ &buf_info->info_list);
+ if (ret) {
+ coap_err("Failed to deliver buf info");
+ status = qdf_status_from_os_return(ret);
+ goto out;
+ }
+
+out:
+ if (request)
+ osif_request_put(request);
+ return qdf_status_to_os_return(status);
+}
+
+/**
+ * wlan_cfg80211_coap_offload_reply_disable() - disable CoAP offload reply
+ * @wiphy: pointer to wireless wiphy structure.
+ * @vdev: pointer to vdev object
+ * @req_id: request id
+ *
+ * Return: 0 on success; error number otherwise
+ */
+static int
+wlan_cfg80211_coap_offload_reply_disable(struct wiphy *wiphy,
+ struct wlan_objmgr_vdev *vdev,
+ uint32_t req_id)
+{
+ void *cookie;
+ QDF_STATUS status;
+ struct osif_request *request;
+ struct coap_buf_info *buf_info;
+ int ret;
+ static const struct osif_request_params params = {
+ .priv_size = sizeof(*buf_info),
+ .timeout_ms = COAP_OFFLOAD_CACHE_GET_TIMEOUT_MS,
+ .dealloc = wlan_cfg80211_dealloc_coap_buf_info,
+ };
+
+ request = osif_request_alloc(&params);
+ if (!request) {
+ coap_err("Request allocation failure");
+ status = QDF_STATUS_E_NOMEM;
+ goto out;
+ }
+
+ buf_info = osif_request_priv(request);
+ qdf_list_create(&buf_info->info_list, 0);
+ buf_info->req_id = req_id;
+ buf_info->vdev_id = wlan_vdev_get_id(vdev);
+
+ cookie = osif_request_cookie(request);
+ status = ucfg_coap_offload_reply_disable(vdev, req_id,
+ wlan_cfg80211_coap_cache_get_cbk, cookie);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ coap_err("Failed to disable offload reply");
+ goto out;
+ }
+
+ ret = osif_request_wait_for_response(request);
+ if (ret) {
+ coap_err("Target response timed out");
+ status = qdf_status_from_os_return(ret);
+ goto out;
+ }
+
+ ret = wlan_cfg80211_coap_offload_cache_deliver(wiphy,
+ &buf_info->info_list);
+ if (ret) {
+ coap_err("Failed to deliver buf info");
+ status = qdf_status_from_os_return(ret);
+ goto out;
+ }
+
+out:
+ if (request)
+ osif_request_put(request);
+ return qdf_status_to_os_return(status);
+}
+
+int
+wlan_cfg80211_coap_offload(struct wiphy *wiphy, struct wlan_objmgr_vdev *vdev,
+ const void *data, int data_len)
+{
+ struct nlattr *tb[COAP_ATTR(MAX) + 1];
+ struct nlattr *attr;
+ uint32_t action, req_id;
+ int ret;
+
+ if (wlan_cfg80211_nla_parse(tb, COAP_ATTR(MAX),
+ data, data_len, coap_offload_policy)) {
+ coap_err("Invalid ATTR");
+ return -EINVAL;
+ }
+
+ if (!tb[COAP_ATTR(ACTION)]) {
+ coap_err("no attr action");
+ return -EINVAL;
+ }
+
+ if (!tb[COAP_ATTR(REQ_ID)]) {
+ coap_err("no attr req id");
+ return -EINVAL;
+ }
+
+ action = nla_get_u32(tb[COAP_ATTR(ACTION)]);
+ req_id = nla_get_u32(tb[COAP_ATTR(REQ_ID)]);
+ switch (action) {
+ case QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_ENABLE:
+ attr = tb[COAP_ATTR(REPLY)];
+ ret = wlan_cfg80211_coap_offload_reply_enable(vdev, req_id,
+ attr);
+ break;
+ case QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_REPLY_DISABLE:
+ ret = wlan_cfg80211_coap_offload_reply_disable(wiphy, vdev,
+ req_id);
+ break;
+ case QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_ENABLE:
+ attr = tb[COAP_ATTR(PERIODIC_TX)];
+ ret = wlan_cfg80211_coap_offload_periodic_tx_enable(vdev,
+ req_id,
+ attr);
+ break;
+ case QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_PERIODIC_TX_DISABLE:
+ ret = wlan_cfg80211_coap_offload_periodic_tx_disable(vdev,
+ req_id);
+ break;
+ case QCA_WLAN_VENDOR_COAP_OFFLOAD_ACTION_CACHE_GET:
+ ret = wlan_cfg80211_coap_offload_cache_get(wiphy, vdev,
+ req_id);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ coap_debug("vdev_id %u action %u req id %u ret %d",
+ wlan_vdev_get_id(vdev), action, req_id, ret);
+ return ret;
+}
diff --git a/os_if/pkt_capture/src/os_if_pkt_capture.c b/os_if/pkt_capture/src/os_if_pkt_capture.c
index 67000b3fb6..0a252e609d 100644
--- a/os_if/pkt_capture/src/os_if_pkt_capture.c
+++ b/os_if/pkt_capture/src/os_if_pkt_capture.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -73,9 +74,6 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter,
struct nlattr *tb[SET_MONITOR_MODE_CONFIG_MAX + 1];
QDF_STATUS status;
- if (tb[SET_MONITOR_MODE_INVALID])
- return QDF_STATUS_E_FAILURE;
-
vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_PKT_CAPTURE_ID);
if (!vdev)
return QDF_STATUS_E_INVAL;
@@ -87,6 +85,11 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter,
return QDF_STATUS_E_INVAL;
}
+ if (tb[SET_MONITOR_MODE_INVALID]) {
+ hdd_objmgr_put_vdev_by_user(vdev, WLAN_PKT_CAPTURE_ID);
+ return QDF_STATUS_E_FAILURE;
+ }
+
if (tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE] &&
nla_get_u32(tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE]) <
PACKET_CAPTURE_DATA_MAX_FILTER) {