qcacld-3.0: Implement api for interop issues ap

Implement the interface to transfer the info between
host driver and firmware about the ap which has interop
issues with the DUT. It is detected by firmware and
forwarded to user sapce for persistent storage. And
user space configs these APs to firmware when the DUT
starts up next time.

CRs-Fixed: 2425202
Change-Id: I2e828d521f0e04862a01fa1c90626f51b7f65796
diff --git a/Kbuild b/Kbuild
index f2a6258..fb7a24e 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1155,6 +1155,11 @@
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_extscan_tlv.o
 endif
 
+ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y)
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_api.o
+WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_interop_issues_ap_tlv.o
+endif
+
 ifeq ($(CONFIG_QCACLD_FEATURE_NAN), y)
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_api.o
 WMI_OBJS += $(WMI_OBJ_DIR)/wmi_unified_nan_tlv.o
@@ -1437,6 +1442,25 @@
 		 $(CP_STATS_DISPATCHER_SRC)/wlan_cp_stats_mc_ucfg_api.o
 endif
 
+###### INTEROP ISSUES AP ########
+INTEROP_ISSUES_AP_OS_IF_SRC      := os_if/interop_issues_ap/src
+INTEROP_ISSUES_AP_TGT_SRC        := components/target_if/interop_issues_ap/src
+INTEROP_ISSUES_AP_CORE_SRC       := components/interop_issues_ap/core/src
+INTEROP_ISSUES_AP_DISPATCHER_SRC := components/interop_issues_ap/dispatcher/src
+
+INTEROP_ISSUES_AP_OS_IF_INC      := -I$(WLAN_ROOT)/os_if/interop_issues_ap/inc
+INTEROP_ISSUES_AP_TGT_INC        := -I$(WLAN_ROOT)/components/target_if/interop_issues_ap/inc
+INTEROP_ISSUES_AP_DISPATCHER_INC := -I$(WLAN_ROOT)/components/interop_issues_ap/dispatcher/inc
+INTEROP_ISSUES_AP_CORE_INC       := -I$(WLAN_ROOT)/components/interop_issues_ap/core/inc
+
+ifeq ($(CONFIG_FEATURE_INTEROP_ISSUES_AP), y)
+INTEROP_ISSUES_AP_OBJS := $(INTEROP_ISSUES_AP_TGT_SRC)/target_if_interop_issues_ap.o \
+		$(INTEROP_ISSUES_AP_CORE_SRC)/wlan_interop_issues_ap_api.o \
+		$(INTEROP_ISSUES_AP_OS_IF_SRC)/wlan_cfg80211_interop_issues_ap.o \
+		$(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_tgt_api.o \
+		$(INTEROP_ISSUES_AP_DISPATCHER_SRC)/wlan_interop_issues_ap_ucfg_api.o
+endif
+
 ######################### NAN #########################
 NAN_CORE_DIR := components/nan/core/src
 NAN_CORE_INC := -I$(WLAN_ROOT)/components/nan/core/inc
@@ -1773,6 +1797,11 @@
 INCS +=		$(CP_STATS_OS_IF_INC)
 INCS +=		$(CP_STATS_TGT_INC)
 INCS +=		$(CP_STATS_DISPATCHER_INC)
+################ INTEROP ISSUES AP ################
+INCS +=		$(INTEROP_ISSUES_AP_OS_IF_INC)
+INCS +=		$(INTEROP_ISSUES_AP_TGT_INC)
+INCS +=		$(INTEROP_ISSUES_AP_DISPATCHER_INC)
+INCS +=		$(INTEROP_ISSUES_AP_CORE_INC)
 ################ NAN POS ################
 INCS +=		$(NAN_CORE_INC)
 INCS +=		$(NAN_UCFG_INC)
@@ -1867,6 +1896,7 @@
 OBJS +=		$(UMAC_OBJMGR_OBJS)
 OBJS +=		$(WIFI_POS_OBJS)
 OBJS +=		$(CP_STATS_OBJS)
+OBJS +=		$(INTEROP_ISSUES_AP_OBJS)
 OBJS +=		$(WLAN_NAN_OBJS)
 OBJS +=		$(UMAC_MGMT_TXRX_OBJS)
 OBJS +=		$(TDLS_OBJS)
@@ -1975,6 +2005,7 @@
 cppflags-$(CONFIG_WLAN_LOGGING_BUFFERS_DYNAMICALLY) += -DWLAN_LOGGING_BUFFERS_DYNAMICALLY
 cppflags-$(CONFIG_WLAN_FEATURE_FILS) += -DWLAN_FEATURE_FILS_SK
 cppflags-$(CONFIG_CP_STATS) += -DQCA_SUPPORT_CP_STATS
+cppflags-$(CONFIG_FEATURE_INTEROP_ISSUES_AP) += -DWLAN_FEATURE_INTEROP_ISSUES_AP
 cppflags-$(CONFIG_FEATURE_MEMDUMP_ENABLE) += -DWLAN_FEATURE_MEMDUMP_ENABLE
 cppflags-$(CONFIG_FEATURE_FW_LOG_PARSING) += -DFEATURE_FW_LOG_PARSING
 
diff --git a/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h b/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h
new file mode 100644
index 0000000..b3de4ca
--- /dev/null
+++ b/components/interop_issues_ap/core/inc/wlan_interop_issues_ap_api.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_interop_issues_ap_api.h
+ *
+ * This header file provide API declarations required for interop issues
+ * ap global context specific to offload
+ */
+
+#ifndef __WLAN_INTEROP_ISSUES_AP_API_H__
+#define __WLAN_INTEROP_ISSUES_AP_API_H__
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+#include <qdf_types.h>
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_interop_issues_ap_public_structs.h>
+
+#define interop_issues_ap_debug(args ...) \
+	QDF_TRACE_DEBUG(QDF_MODULE_ID_INTEROP_ISSUES_AP, ## args)
+#define interop_issues_ap_err(args ...) \
+	QDF_TRACE_ERROR(QDF_MODULE_ID_INTEROP_ISSUES_AP, ## args)
+
+/**
+ * struct interop_issues_ap_psoc_priv_obj - psoc private object
+ * @lock: qdf spin lock
+ * @soc: pointer to psoc object
+ * @cbs: interop issues ap ps event callbacks
+ * @tx_ops: interop issues ap ps tx ops
+ */
+struct interop_issues_ap_psoc_priv_obj {
+	qdf_spinlock_t lock;
+	struct wlan_objmgr_psoc *soc;
+	struct wlan_interop_issues_ap_callbacks cbs;
+	struct wlan_interop_issues_ap_tx_ops tx_ops;
+};
+
+/**
+ * wlan_interop_issues_ap_psoc_enable() - interop issues ap psoc enable
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *soc);
+
+/**
+ * wlan_interop_issues_ap_psoc_disable() - interop issues ap psoc disable
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *soc);
+
+/**
+ * wlan_interop_issues_ap_init() - API to init component
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_interop_issues_ap_init(void);
+
+/**
+ * wlan_interop_issues_ap_deinit() - API to deinit component
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS wlan_interop_issues_ap_deinit(void);
+
+/**
+ * interop_issues_ap_get_psoc_priv_obj() - get priv object from psoc object
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to interop issues ap psoc private object
+ */
+static inline
+struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_get_psoc_priv_obj(
+						struct wlan_objmgr_psoc *psoc)
+{
+	struct interop_issues_ap_psoc_priv_obj *obj;
+
+	if (!psoc)
+		return NULL;
+
+	obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+					WLAN_UMAC_COMP_INTEROP_ISSUES_AP);
+
+	return obj;
+}
+
+/**
+ * interop_issues_ap_psoc_get_tx_ops() - get TX ops from the private object
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to TX op callback
+ */
+static inline
+struct wlan_interop_issues_ap_tx_ops *interop_issues_ap_psoc_get_tx_ops(
+						struct wlan_objmgr_psoc *psoc)
+{
+	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_priv;
+
+	if (!psoc)
+		return NULL;
+
+	interop_issues_ap_priv = interop_issues_ap_get_psoc_priv_obj(psoc);
+	if (!interop_issues_ap_priv) {
+		interop_issues_ap_err("psoc private object is null");
+		return NULL;
+	}
+
+	return &interop_issues_ap_priv->tx_ops;
+}
+
+/**
+ * interop_issues_ap_psoc_get_cbs() - get RX ops from private object
+ * @psoc: pointer to psoc object
+ *
+ * Return: pointer to RX op callback
+ */
+static inline
+struct wlan_interop_issues_ap_callbacks *interop_issues_ap_psoc_get_cbs(
+						struct wlan_objmgr_psoc *psoc)
+{
+	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_priv;
+
+	if (!psoc)
+		return NULL;
+
+	interop_issues_ap_priv = interop_issues_ap_get_psoc_priv_obj(psoc);
+	if (!interop_issues_ap_priv) {
+		interop_issues_ap_err("psoc private object is null");
+		return NULL;
+	}
+
+	return &interop_issues_ap_priv->cbs;
+}
+#endif
+#endif
diff --git a/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c b/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c
new file mode 100644
index 0000000..88d08fb
--- /dev/null
+++ b/components/interop_issues_ap/core/src/wlan_interop_issues_ap_api.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_interop_issues_ap_api.c
+ */
+#include <wlan_interop_issues_ap_ucfg_api.h>
+#include <wlan_interop_issues_ap_api.h>
+#include <target_if_interop_issues_ap.h>
+
+/**
+ * interop_issues_ap_psoc_obj_created_notification() - PSOC obj create callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is created.
+ *
+ * Return: Success or Failure
+ */
+static QDF_STATUS
+interop_issues_ap_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc,
+						void *arg_list)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj;
+
+	interop_issues_ap_obj = qdf_mem_malloc(sizeof(*interop_issues_ap_obj));
+	if (!interop_issues_ap_obj)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_spinlock_create(&interop_issues_ap_obj->lock);
+	status = wlan_objmgr_psoc_component_obj_attach(psoc,
+					WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+					interop_issues_ap_obj,
+					QDF_STATUS_SUCCESS);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("obj attach with psoc failed");
+		goto interop_issues_ap_psoc_attach_failed;
+	}
+
+	target_if_interop_issues_ap_register_tx_ops(psoc,
+					&interop_issues_ap_obj->tx_ops);
+
+	return QDF_STATUS_SUCCESS;
+
+interop_issues_ap_psoc_attach_failed:
+	qdf_spinlock_destroy(&interop_issues_ap_obj->lock);
+	qdf_mem_free(interop_issues_ap_obj);
+	return status;
+}
+
+/**
+ * interop_issues_ap_psoc_obj_destroyed_notification() - obj delete callback
+ * @psoc: PSOC object
+ * @arg_list: Variable argument list
+ *
+ * This callback is registered with object manager during initialization to
+ * get notified when the object is deleted.
+ *
+ * Return: Success or Failure
+ */
+static QDF_STATUS
+interop_issues_ap_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc,
+						  void *arg_list)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct interop_issues_ap_psoc_priv_obj *interop_issues_ap_obj;
+
+	interop_issues_ap_obj = interop_issues_ap_get_psoc_priv_obj(psoc);
+
+	if (!interop_issues_ap_obj) {
+		interop_issues_ap_err("interop_issues_ap_obj is NULL");
+		return QDF_STATUS_E_FAULT;
+	}
+	target_if_interop_issues_ap_unregister_tx_ops(psoc,
+					&interop_issues_ap_obj->tx_ops);
+
+	status = wlan_objmgr_psoc_component_obj_detach(psoc,
+					WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+					interop_issues_ap_obj);
+	if (QDF_IS_STATUS_ERROR(status))
+		interop_issues_ap_err("interop_issues_ap_obj detach failed");
+
+	qdf_spinlock_destroy(&interop_issues_ap_obj->lock);
+	qdf_mem_free(interop_issues_ap_obj);
+
+	return status;
+}
+
+QDF_STATUS wlan_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return target_if_interop_issues_ap_register_event_handler(psoc);
+}
+
+QDF_STATUS wlan_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return target_if_interop_issues_ap_unregister_event_handler(psoc);
+}
+
+QDF_STATUS wlan_interop_issues_ap_init(void)
+{
+	QDF_STATUS status;
+
+	/* register psoc create handler functions. */
+	status = wlan_objmgr_register_psoc_create_handler(
+			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+			interop_issues_ap_psoc_obj_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("register create handler failed");
+		return status;
+	}
+
+	/* register psoc delete handler functions. */
+	status = wlan_objmgr_register_psoc_destroy_handler(
+			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+			interop_issues_ap_psoc_obj_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("register destroy handler failed");
+		status = wlan_objmgr_unregister_psoc_create_handler(
+				WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+				interop_issues_ap_psoc_obj_created_notification,
+				NULL);
+	}
+
+	return status;
+}
+
+QDF_STATUS wlan_interop_issues_ap_deinit(void)
+{
+	QDF_STATUS ret = QDF_STATUS_SUCCESS, status;
+
+	/* unregister psoc delete handler functions. */
+	status = wlan_objmgr_unregister_psoc_destroy_handler(
+			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+			interop_issues_ap_psoc_obj_destroyed_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("unregister destroy handler failed");
+		ret = status;
+	}
+
+	/* unregister psoc create handler functions. */
+	status = wlan_objmgr_unregister_psoc_create_handler(
+			WLAN_UMAC_COMP_INTEROP_ISSUES_AP,
+			interop_issues_ap_psoc_obj_created_notification,
+			NULL);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("unregister create handler failed");
+		ret = status;
+	}
+
+	return ret;
+}
diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h
new file mode 100644
index 0000000..2afd61c
--- /dev/null
+++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_public_structs.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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 interop issues ap structure definations
+ */
+
+#ifndef _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_
+#define _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+#include <qdf_types.h>
+#include <wlan_objmgr_psoc_obj.h>
+
+#define MAX_INTEROP_ISSUES_AP_NUM 20
+
+/**
+ * struct wlan_interop_issues_ap_info - interop issues ap info
+ * @count: the number of interop issues ap
+ * @rap_items: interop issues ap items
+ */
+struct wlan_interop_issues_ap_info {
+	uint32_t count;
+	struct qdf_mac_addr rap_items[MAX_INTEROP_ISSUES_AP_NUM];
+};
+
+/**
+ * struct wlan_interop_issues_ap_event - interop issues ap event
+ * @pdev: pdev object
+ * @psoc: psoc object
+ * @pdev_id: pdev id number
+ * @rap_addr: interop issues ap mac address
+ */
+struct wlan_interop_issues_ap_event {
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_objmgr_psoc *psoc;
+	uint32_t pdev_id;
+	struct qdf_mac_addr rap_addr;
+};
+
+/**
+ * struct wlan_interop_issues_ap_callbacks - interop issues ap callbacks
+ * @os_if_interop_issues_ap_event_handler: OS IF callback for handling events
+ */
+struct wlan_interop_issues_ap_callbacks {
+	void (*os_if_interop_issues_ap_event_handler)
+				(struct wlan_interop_issues_ap_event *event);
+};
+
+/**
+ * struct wlan_interop_issues_ap_tx_ops - structure of tx func pointers
+ * @set_rap_ps: handler for TX operations for the interop issues ap ps config
+ */
+struct wlan_interop_issues_ap_tx_ops {
+	QDF_STATUS (*set_rap_ps)(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_interop_issues_ap_info *rap);
+};
+#endif
+#endif /* _WLAN_INTEROP_ISSUES_AP_STRUCTS_H_ */
diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h
new file mode 100644
index 0000000..6f5b2c8
--- /dev/null
+++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_tgt_api.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_interop_issues_ap_tgt_api.h
+ *
+ * This header file provide with API declarations to interface with Southbound
+ */
+#ifndef __WLAN_INTEROP_ISSUES_AP_TGT_API_H__
+#define __WLAN_INTEROP_ISSUES_AP_TGT_API_H__
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+/**
+ * tgt_interop_issues_ap_info_callback() - interop issues ap info callback
+ * @psoc: the pointer to psoc object manager
+ * @rap: the interop issues ap mac address
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+tgt_interop_issues_ap_info_callback(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_interop_issues_ap_event *rap);
+
+/**
+ * tgt_set_interop_issues_ap_req(): API to set interop issues ap to lmac
+ * @rx_ops: rx ops struct
+ * @rap: the pointer to interop issues ap info
+ *
+ * Return: status of operation
+ */
+QDF_STATUS
+tgt_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc,
+			      struct wlan_interop_issues_ap_info *rap);
+#endif
+#endif /* __WLAN_INTEROP_ISSUES_AP_TGT_API_H__ */
diff --git a/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h
new file mode 100644
index 0000000..4d95087
--- /dev/null
+++ b/components/interop_issues_ap/dispatcher/inc/wlan_interop_issues_ap_ucfg_api.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_interop_issues_ap_ucfg_api.h
+ *
+ * This header file maintain API declaration required for northbound interaction
+ */
+
+#ifndef __WLAN_INTEROP_ISSUES_AP_UCFG_API_H__
+#define __WLAN_INTEROP_ISSUES_AP_UCFG_API_H__
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+#include <qdf_status.h>
+#include <qdf_types.h>
+#include <wlan_interop_issues_ap_public_structs.h>
+
+/**
+ * ucfg_interop_issues_ap_psoc_enable() - interop issues ap component enable
+ * @psoc: the point to psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_interop_issues_ap_psoc_disable() - interop issues ap component disable
+ * @psoc: the point to psoc object
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc);
+
+/**
+ * ucfg_interop_issues_ap_init() - interop issues ap component initialization
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ucfg_interop_issues_ap_init(void);
+
+/**
+ * ucfg_interop_issues_ap_deinit() - interop issues ap component de-init
+ *
+ * Return: QDF_STATUS_SUCCESS - in case of success
+ */
+QDF_STATUS ucfg_interop_issues_ap_deinit(void);
+
+/**
+ * ucfg_register_interop_issues_ap_callback() - API to register callback
+ * @cbs: pointer to callback structure
+ *
+ * Return: none
+ */
+void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev,
+				struct wlan_interop_issues_ap_callbacks *cbs);
+
+/**
+ * ucfg_set_interop_issues_ap_config() - API to set interop issues ap
+ * @vdev: the pointer of vdev object
+ * @rap: the pointer of interop issues ap info
+ *
+ * Return: none
+ */
+QDF_STATUS ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev,
+				     struct wlan_interop_issues_ap_info *rap);
+#else
+static inline
+QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline
+QDF_STATUS ucfg_interop_issues_ap_init(void) { return QDF_STATUS_SUCCESS; }
+
+static inline
+QDF_STATUS ucfg_interop_issues_ap_deinit(void) { return QDF_STATUS_SUCCESS; }
+#endif /* WLAN_FEATURE_INTEROP_ISSUES_AP */
+#endif /* __WLAN_RAP_PS_UCFG_API_H__ */
diff --git a/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c
new file mode 100644
index 0000000..dd6cdae
--- /dev/null
+++ b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_tgt_api.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_interop_issues_ap_tgt_api.c
+ *
+ * This file provide API definitions to update interop issues ap from interface
+ */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <scheduler_api.h>
+#include <wlan_interop_issues_ap_api.h>
+#include <wlan_interop_issues_ap_tgt_api.h>
+
+static QDF_STATUS wlan_interop_issues_ap_flush_cbk(struct scheduler_msg *msg)
+{
+	if (msg->bodyptr) {
+		qdf_mem_free(msg->bodyptr);
+		msg->bodyptr = NULL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+static void wlan_interop_issues_ap_info_cbk(struct scheduler_msg *msg)
+{
+	struct wlan_interop_issues_ap_event *data;
+	struct wlan_interop_issues_ap_callbacks *cbs;
+
+	data = msg->bodyptr;
+	data->pdev = wlan_objmgr_get_pdev_by_id(data->psoc,
+						data->pdev_id,
+						WLAN_INTEROP_ISSUES_AP_ID);
+	if (!data->pdev) {
+		interop_issues_ap_err("pdev is null.");
+		goto err;
+	}
+
+	cbs = interop_issues_ap_psoc_get_cbs(data->psoc);
+	if (cbs && cbs->os_if_interop_issues_ap_event_handler)
+		cbs->os_if_interop_issues_ap_event_handler(msg->bodyptr);
+
+	wlan_objmgr_pdev_release_ref(data->pdev, WLAN_INTEROP_ISSUES_AP_ID);
+err:
+	qdf_mem_free(data);
+	msg->bodyptr = NULL;
+}
+
+QDF_STATUS tgt_interop_issues_ap_info_callback(struct wlan_objmgr_psoc *psoc,
+				      struct wlan_interop_issues_ap_event *rap)
+{
+	struct scheduler_msg msg = {0};
+	QDF_STATUS status;
+	struct wlan_interop_issues_ap_event *data;
+
+	data = qdf_mem_malloc(sizeof(*data));
+	if (!data)
+		return QDF_STATUS_E_NOMEM;
+
+	qdf_mem_copy(data, rap, sizeof(*data));
+
+	msg.bodyptr = data;
+	msg.callback = wlan_interop_issues_ap_info_cbk;
+	msg.flush_callback = wlan_interop_issues_ap_flush_cbk;
+
+	status = scheduler_post_message(QDF_MODULE_ID_INTEROP_ISSUES_AP,
+					QDF_MODULE_ID_INTEROP_ISSUES_AP,
+					QDF_MODULE_ID_TARGET_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		interop_issues_ap_err("scheduler msg posting failed");
+		qdf_mem_free(msg.bodyptr);
+		msg.bodyptr = NULL;
+	}
+
+	return status;
+}
+
+QDF_STATUS tgt_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc,
+				struct wlan_interop_issues_ap_info *rap)
+{
+	struct interop_issues_ap_psoc_priv_obj *obj;
+
+	obj = interop_issues_ap_get_psoc_priv_obj(psoc);
+	if (!obj || !obj->tx_ops.set_rap_ps)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	return obj->tx_ops.set_rap_ps(psoc, rap);
+}
diff --git a/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c
new file mode 100644
index 0000000..e53524c
--- /dev/null
+++ b/components/interop_issues_ap/dispatcher/src/wlan_interop_issues_ap_ucfg_api.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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: This file contains interop issues ap north bound interface definitions
+ */
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_interop_issues_ap_ucfg_api.h>
+#include <wlan_interop_issues_ap_tgt_api.h>
+#include <wlan_cfg80211_interop_issues_ap.h>
+#include <wlan_interop_issues_ap_api.h>
+
+QDF_STATUS
+ucfg_set_interop_issues_ap_config(struct wlan_objmgr_vdev *vdev,
+				  struct wlan_interop_issues_ap_info *rap)
+{
+	return tgt_set_interop_issues_ap_req(wlan_vdev_get_psoc(vdev), rap);
+}
+
+void ucfg_register_interop_issues_ap_callback(struct wlan_objmgr_pdev *pdev,
+				   struct wlan_interop_issues_ap_callbacks *cb)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct interop_issues_ap_psoc_priv_obj *obj;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc) {
+		interop_issues_ap_err("psoc object is NULL");
+		return;
+	}
+
+	obj = interop_issues_ap_get_psoc_priv_obj(psoc);
+	if (!obj) {
+		interop_issues_ap_err("interop issues ap priv obj is NULL");
+		return;
+	}
+
+	obj->cbs.os_if_interop_issues_ap_event_handler =
+			cb->os_if_interop_issues_ap_event_handler;
+}
+
+QDF_STATUS ucfg_interop_issues_ap_psoc_enable(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_interop_issues_ap_psoc_enable(psoc);
+}
+
+QDF_STATUS ucfg_interop_issues_ap_psoc_disable(struct wlan_objmgr_psoc *psoc)
+{
+	return wlan_interop_issues_ap_psoc_disable(psoc);
+}
+
+QDF_STATUS ucfg_interop_issues_ap_init(void)
+{
+	return wlan_interop_issues_ap_init();
+}
+
+QDF_STATUS ucfg_interop_issues_ap_deinit(void)
+{
+	return wlan_interop_issues_ap_deinit();
+}
diff --git a/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h b/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h
new file mode 100644
index 0000000..b65314a
--- /dev/null
+++ b/components/target_if/interop_issues_ap/inc/target_if_interop_issues_ap.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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: offload lmac interface APIs for interop issues ap
+ */
+#ifndef __TARGET_IF_INTEROP_ISSUES_AP_H__
+#define __TARGET_IF_INTEROP_ISSUES_AP_H__
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <qdf_status.h>
+#include <wlan_lmac_if_def.h>
+#include <wlan_interop_issues_ap_public_structs.h>
+
+/**
+ * target_if_interop_issues_ap_register_event_handler() - register callback
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_interop_issues_ap_register_event_handler(
+						struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_interop_issues_ap_unregister_event_handler() - unregister callback
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_interop_issues_ap_unregister_event_handler(
+						struct wlan_objmgr_psoc *psoc);
+
+/**
+ * target_if_interop_issues_ap_register_tx_ops() - register tx ops funcs
+ * @psoc: the pointer of psoc object
+ * @tx_ops: pointer to rap_ps tx ops
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS
+target_if_interop_issues_ap_register_tx_ops(struct wlan_objmgr_psoc *psoc,
+				struct wlan_interop_issues_ap_tx_ops *tx_ops);
+/**
+ * target_if_interop_issues_ap_unregister_tx_ops() - unregister tx ops funcs
+ * @psoc: the pointer of psoc object
+ * @tx_ops: pointer to rap_ps tx ops
+ *
+ * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
+ */
+QDF_STATUS
+target_if_interop_issues_ap_unregister_tx_ops(struct wlan_objmgr_psoc *psoc,
+				 struct wlan_interop_issues_ap_tx_ops *tx_ops);
+#endif
+#endif /* __TARGET_IF_INTEROP_ISSUES_AP_H__ */
diff --git a/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c b/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c
new file mode 100644
index 0000000..5cbed5b
--- /dev/null
+++ b/components/target_if/interop_issues_ap/src/target_if_interop_issues_ap.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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: target_if_interop_issues_ap.c
+ *
+ * This file provide definition for APIs registered through lmac Tx Ops
+ */
+
+#include <qdf_mem.h>
+#include <qdf_status.h>
+#include <qdf_types.h>
+#include <target_if.h>
+#include <wlan_tgt_def_config.h>
+#include <wlan_osif_priv.h>
+#include <wlan_interop_issues_ap_tgt_api.h>
+#include <wlan_interop_issues_ap_api.h>
+#include <target_if_interop_issues_ap.h>
+#include <wmi_unified_interop_issues_ap_api.h>
+
+/**
+ * target_if_interop_issues_ap_event_handler() - callback for event
+ * @event: firmware event
+ * @len: the event length
+ *
+ * Return: 0 or error status
+ */
+static int target_if_interop_issues_ap_event_handler(ol_scn_t sc,
+						     uint8_t *event,
+						     uint32_t len)
+{
+	struct wlan_objmgr_psoc *psoc;
+	struct wmi_unified *wmi_handle;
+	struct wlan_interop_issues_ap_event data = {0};
+	int ret;
+
+	TARGET_IF_ENTER();
+
+	psoc = target_if_get_psoc_from_scn_hdl(sc);
+	if (!psoc) {
+		target_if_err("psoc ptr is NULL");
+		return -EINVAL;
+	}
+	data.psoc = psoc;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return -EINVAL;
+	}
+
+	ret = wmi_extract_interop_issues_ap_ev_param(wmi_handle, event, &data);
+	if (ret)
+		return -EINVAL;
+
+	target_if_debug("interop issues ap macaddr: " QDF_MAC_ADDR_STR,
+			QDF_MAC_ADDR_ARRAY(data.rap_addr.bytes));
+
+	return tgt_interop_issues_ap_info_callback(psoc, &data);
+}
+
+/**
+ * target_if_interop_issues_ap_register_event_handler() - register callback
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_interop_issues_ap_register_event_handler(
+						struct wlan_objmgr_psoc *psoc)
+{
+	int ret_val;
+	struct wmi_unified *wmi_handle;
+
+	if (!psoc) {
+		target_if_err("PSOC is NULL!");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	ret_val =
+	   wmi_unified_register_event_handler(wmi_handle,
+				wmi_pdev_interop_issues_ap_event_id,
+				target_if_interop_issues_ap_event_handler,
+				WMI_RX_WORK_CTX);
+	if (ret_val)
+		target_if_err("Failed to register event cb");
+
+	return qdf_status_from_os_return(ret_val);
+}
+
+/**
+ * target_if_interop_issues_ap_unregister_event_handler() - unregister callback
+ * @psoc: the pointer to psoc object
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+target_if_interop_issues_ap_unregister_event_handler(
+						struct wlan_objmgr_psoc *psoc)
+{
+	struct wmi_unified *wmi_handle;
+
+	if (!psoc) {
+		target_if_err("PSOC is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null");
+		return QDF_STATUS_E_INVAL;
+	}
+	wmi_unified_unregister_event_handler(wmi_handle,
+					wmi_pdev_interop_issues_ap_event_id);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * target_if_set_interop_issues_ap_req() - API to send stats request to wmi
+ * @psoc: pointer to psoc object
+ * @raq: pointer to interop issues ap info
+ *
+ * Return: status of operation.
+ */
+static QDF_STATUS
+target_if_set_interop_issues_ap_req(struct wlan_objmgr_psoc *psoc,
+				    struct wlan_interop_issues_ap_info *rap)
+{
+	struct wmi_unified *wmi_handle;
+
+	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
+	if (!wmi_handle) {
+		target_if_err("wmi_handle is null.");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return wmi_unified_set_rap_ps_cmd(wmi_handle, rap);
+}
+
+QDF_STATUS
+target_if_interop_issues_ap_register_tx_ops(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_interop_issues_ap_tx_ops *tx_ops)
+{
+	if (!tx_ops) {
+		target_if_err("tx ops is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops->set_rap_ps = target_if_set_interop_issues_ap_req;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+target_if_interop_issues_ap_unregister_tx_ops(struct wlan_objmgr_psoc *psoc,
+				  struct wlan_interop_issues_ap_tx_ops *tx_ops)
+{
+	if (!tx_ops) {
+		target_if_err("tx ops is NULL!");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	tx_ops->set_rap_ps = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
diff --git a/configs/default_defconfig b/configs/default_defconfig
index 2bd50db..943be72 100644
--- a/configs/default_defconfig
+++ b/configs/default_defconfig
@@ -646,6 +646,7 @@
 endif
 
 CONFIG_CP_STATS := y
+CONFIG_FEATURE_INTEROP_ISSUES_AP := y
 
 CONFIG_FEATURE_WLAN_WAPI := y
 
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 5493683..894dfe7 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -137,6 +137,7 @@
 #include "nan_ucfg_api.h"
 #include "wlan_fwol_ucfg_api.h"
 #include "wlan_cfg80211_crypto.h"
+#include "wlan_cfg80211_interop_issues_ap.h"
 #include "wlan_scan_ucfg_api.h"
 #include "wlan_hdd_coex_config.h"
 #include "wlan_hdd_bcn_recv.h"
@@ -1462,6 +1463,8 @@
 	},
 #endif /*FEATURE_LFR_SUBNET_DETECTION */
 
+	FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX
+
 	[QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX] = {
 		.vendor_id = QCA_NL80211_VENDOR_ID,
 		.subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP
@@ -12803,6 +12806,7 @@
 	},
 #endif
 	FEATURE_RSSI_MONITOR_VENDOR_COMMANDS
+	FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS
 
 #ifdef WLAN_NS_OFFLOAD
 	{
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index ccf6d2d..a295be7 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -152,6 +152,7 @@
 #include "wlan_mlme_main.h"
 #include "wlan_p2p_cfg_api.h"
 #include "wlan_cfg80211_p2p.h"
+#include "wlan_cfg80211_interop_issues_ap.h"
 #include "wlan_tdls_cfg_api.h"
 #include <wlan_hdd_rssi_monitor.h>
 #include "wlan_mlme_ucfg_api.h"
@@ -165,6 +166,7 @@
 #include <wlan_hdd_spectralscan.h>
 #include "wlan_green_ap_ucfg_api.h"
 #include <wlan_p2p_ucfg_api.h>
+#include <wlan_interop_issues_ap_ucfg_api.h>
 #include <target_type.h>
 #include <wlan_hdd_debugfs_coex.h>
 
@@ -319,6 +321,7 @@
 	[QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
 	[QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
 	[QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
+	[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
 };
 
 struct notifier_block hdd_netdev_notifier;
@@ -11945,6 +11948,7 @@
 	ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
 	hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
 	hdd_debugfs_mws_coex_info_init(hdd_ctx);
+	wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
 
 	hdd_exit();
 
@@ -13102,10 +13106,14 @@
 	if (QDF_IS_STATUS_ERROR(status))
 		goto nan_deinit;
 
-	status = policy_mgr_init();
+	status = ucfg_interop_issues_ap_init();
 	if (QDF_IS_STATUS_ERROR(status))
 		goto p2p_deinit;
 
+	status = policy_mgr_init();
+	if (QDF_IS_STATUS_ERROR(status))
+		goto interop_issues_ap_deinit;
+
 	status = ucfg_tdls_init();
 	if (QDF_IS_STATUS_ERROR(status))
 		goto policy_deinit;
@@ -13114,6 +13122,8 @@
 
 policy_deinit:
 	policy_mgr_deinit();
+interop_issues_ap_deinit:
+	ucfg_interop_issues_ap_deinit();
 p2p_deinit:
 	ucfg_p2p_deinit();
 nan_deinit:
@@ -13152,6 +13162,7 @@
 	/* deinitialize non-converged components */
 	ucfg_tdls_deinit();
 	policy_mgr_deinit();
+	ucfg_interop_issues_ap_deinit();
 	ucfg_p2p_deinit();
 	nan_deinit();
 	ucfg_action_oui_deinit();
@@ -13228,6 +13239,7 @@
 	disa_psoc_enable(psoc);
 	nan_psoc_enable(psoc);
 	p2p_psoc_enable(psoc);
+	ucfg_interop_issues_ap_psoc_enable(psoc);
 	policy_mgr_psoc_enable(psoc);
 	ucfg_tdls_psoc_enable(psoc);
 }
@@ -13236,6 +13248,7 @@
 {
 	ucfg_tdls_psoc_disable(psoc);
 	policy_mgr_psoc_disable(psoc);
+	ucfg_interop_issues_ap_psoc_disable(psoc);
 	p2p_psoc_disable(psoc);
 	nan_psoc_disable(psoc);
 	disa_psoc_disable(psoc);
diff --git a/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h b/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h
new file mode 100644
index 0000000..24a7cd2
--- /dev/null
+++ b/os_if/interop_issues_ap/inc/wlan_cfg80211_interop_issues_ap.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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_cfg80211_interop_issues_ap.h
+ *
+ * This Header file provide declaration for cfg80211 command handler API
+ */
+
+#ifndef __WLAN_CFG80211_INTEROP_ISSUES_AP_H__
+#define __WLAN_CFG80211_INTEROP_ISSUES_AP_H__
+
+#include <wlan_objmgr_cmn.h>
+#include <qdf_types.h>
+#include <net/cfg80211.h>
+
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+
+#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS \
+{ \
+	.info.vendor_id = QCA_NL80211_VENDOR_ID, \
+	.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP, \
+	.flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
+		 WIPHY_VENDOR_CMD_NEED_NETDEV | \
+		 WIPHY_VENDOR_CMD_NEED_RUNNING, \
+	.doit = wlan_cfg80211_set_interop_issues_ap_config \
+},
+
+#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX \
+	[QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP_INDEX] = { \
+		.vendor_id = QCA_NL80211_VENDOR_ID, \
+		.subcmd = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP \
+	},
+
+/**
+ * wlan_cfg80211_init_interop_issues_ap() - init interop issues ap setting
+ * @pdev: the pointer of pdev object
+ *
+ * Return: none
+ */
+void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_cfg80211_set_interop_issues_ap_config() - set interop issues ap config
+ * @wiphy: pointer to wireless wiphy structure
+ * @wdev: pointer to wireless_dev structure
+ * @data: Pointer to the data to be passed via vendor interface
+ * @data_len: Length of the data to be passed
+ *
+ * Return: Return the Success or Failure code
+ */
+int wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data, int data_len);
+#else
+static inline
+void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev) {}
+#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS
+#define FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX
+#endif
+#endif /* __WLAN_CFG80211_INTEROP_ISSUES_AP_H__ */
diff --git a/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c b/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c
new file mode 100644
index 0000000..dc65abe
--- /dev/null
+++ b/os_if/interop_issues_ap/src/wlan_cfg80211_interop_issues_ap.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. 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 <qdf_list.h>
+#include <qdf_status.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <wlan_cfg80211.h>
+#include <wlan_osif_priv.h>
+#include <wlan_interop_issues_ap_ucfg_api.h>
+#include <wlan_cfg80211_interop_issues_ap.h>
+#include <osif_psoc_sync.h>
+#include <qdf_mem.h>
+#include <wlan_utility.h>
+#include "wlan_hdd_main.h"
+#include "cfg_ucfg_api.h"
+
+const struct nla_policy
+interop_issues_ap_policy[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1] = {
+	[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_TYPE] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t) },
+	[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST] = {
+						.type = NLA_U32,
+						.len = sizeof(uint32_t) },
+	[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID] = {
+						.type = NLA_UNSPEC,
+						.len = QDF_MAC_ADDR_SIZE },
+};
+
+/**
+ * wlan_cfg80211_send_interop_issues_ap_cb() - report information
+ * @data: interop issues ap mac received from fw
+ *
+ * Generate a wlan interop issues ap info package and send it to user
+ * space daemon through netlink.
+ *
+ * Return: none
+ */
+static void
+wlan_cfg80211_send_interop_issues_ap_cb(
+				struct wlan_interop_issues_ap_event *data)
+{
+	struct wlan_objmgr_pdev *pdev;
+	struct pdev_osif_priv *os_priv;
+	struct sk_buff *skb;
+	uint32_t index, len;
+
+	if (!data) {
+		cfg80211_err("Invalid result.");
+		return;
+	}
+
+	pdev = data->pdev;
+	if (!pdev) {
+		cfg80211_err("pdev is null.");
+		return;
+	}
+	os_priv = wlan_pdev_get_ospriv(pdev);
+	if (!os_priv) {
+		cfg80211_err("os_priv is null.");
+		return;
+	}
+
+	index = QCA_NL80211_VENDOR_SUBCMD_INTEROP_ISSUES_AP_INDEX;
+	len = nla_total_size(QDF_MAC_ADDR_SIZE + NLMSG_HDRLEN);
+	skb = cfg80211_vendor_event_alloc(os_priv->wiphy, NULL, len, index,
+					  GFP_KERNEL);
+	if (!skb) {
+		cfg80211_err("skb alloc failed");
+		return;
+	}
+
+	cfg80211_debug("interop issues ap mac:" QDF_MAC_ADDR_STR,
+		       QDF_MAC_ADDR_ARRAY(data->rap_addr.bytes));
+
+	if (nla_put(skb,
+		    QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID,
+		    QDF_MAC_ADDR_SIZE, data->rap_addr.bytes)) {
+		cfg80211_err("nla put fail");
+		kfree_skb(skb);
+		return;
+	}
+
+	cfg80211_vendor_event(skb, GFP_KERNEL);
+}
+
+static void wlan_interop_issues_ap_register_cbk(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_interop_issues_ap_callbacks cb;
+
+	cb.os_if_interop_issues_ap_event_handler =
+					wlan_cfg80211_send_interop_issues_ap_cb;
+	ucfg_register_interop_issues_ap_callback(pdev, &cb);
+}
+
+/**
+ * wlan_parse_interop_issues_ap() - parse the interop issues ap info
+ * @interop_issues_ap: the pointer of interop issues ap
+ * @attr: list of attributes
+ *
+ * Return: 0 on success; error number on failure
+ */
+static int
+wlan_parse_interop_issues_ap(struct qdf_mac_addr *interop_issues_ap,
+			     struct nlattr *attr)
+{
+	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1];
+	struct nlattr *curr_attr = NULL;
+	uint32_t rem;
+	qdf_size_t i = 0;
+
+	nla_for_each_nested(curr_attr, attr, rem) {
+		if (i == MAX_INTEROP_ISSUES_AP_NUM) {
+			cfg80211_err("Ignoring excess");
+			break;
+		}
+
+		if (wlan_cfg80211_nla_parse(tb2,
+				QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX,
+				nla_data(curr_attr),
+				nla_len(curr_attr),
+				interop_issues_ap_policy)) {
+			cfg80211_err("nla_parse failed");
+			return -EINVAL;
+		}
+		if (!tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID]) {
+			cfg80211_err("attr addr failed");
+			return -EINVAL;
+		}
+		nla_memcpy(interop_issues_ap[i].bytes,
+			   tb2[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_BSSID],
+			   QDF_MAC_ADDR_SIZE);
+		cfg80211_debug(QDF_MAC_ADDR_STR,
+			       QDF_MAC_ADDR_ARRAY(interop_issues_ap[i].bytes));
+		i++;
+	}
+
+	return i;
+}
+
+/**
+ * __wlan_cfg80211_set_interop_issues_ap_config() - set config status
+ * @wiphy: WIPHY structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of the data received
+ *
+ * Return: 0 on success and errno on failure
+ */
+static int
+__wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy,
+					     struct wireless_dev *wdev,
+					     const void *data, int data_len)
+{
+	struct net_device *dev = wdev->netdev;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX + 1];
+	struct nlattr *attr;
+	uint32_t count = 0;
+	struct wlan_interop_issues_ap_info interop_issues_ap = {0};
+
+	if (wlan_cfg80211_nla_parse(tb,
+				    QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_MAX,
+				    data, data_len,
+				    interop_issues_ap_policy)) {
+		cfg80211_err("Invalid ATTR");
+		return -EINVAL;
+	}
+
+	attr = tb[QCA_WLAN_VENDOR_ATTR_INTEROP_ISSUES_AP_LIST];
+	if (attr) {
+		count =
+		     wlan_parse_interop_issues_ap(interop_issues_ap.rap_items,
+						  attr);
+		if (count < 0)
+			return -EINVAL;
+	}
+
+	cfg80211_debug("Num of interop issues ap: %d", count);
+	interop_issues_ap.count = count;
+
+	/*
+	 * need to figure out a converged way of obtaining the vdev for
+	 * a given netdev that doesn't involve the legacy mechanism.
+	 */
+	ucfg_set_interop_issues_ap_config(adapter->vdev, &interop_issues_ap);
+
+	return 0;
+}
+
+int wlan_cfg80211_set_interop_issues_ap_config(struct wiphy *wiphy,
+					       struct wireless_dev *wdev,
+					       const void *data, int data_len)
+{
+	struct osif_psoc_sync *psoc_sync;
+	int ret;
+
+	ret = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
+	if (ret)
+		return ret;
+
+	ret = __wlan_cfg80211_set_interop_issues_ap_config(wiphy, wdev,
+							   data, data_len);
+	osif_psoc_sync_op_stop(psoc_sync);
+
+	return ret;
+}
+
+void wlan_cfg80211_init_interop_issues_ap(struct wlan_objmgr_pdev *pdev)
+{
+	/*
+	 * the special mac is used to trigger uplayer sets
+	 * interop issues ap list to fw when driver reloads but
+	 * cnss-daemon does not restart.
+	 */
+	uint8_t fmac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	struct wlan_interop_issues_ap_event data;
+
+	wlan_interop_issues_ap_register_cbk(pdev);
+
+	data.pdev = pdev;
+	qdf_mem_copy(data.rap_addr.bytes, fmac, QDF_MAC_ADDR_SIZE);
+
+	wlan_cfg80211_send_interop_issues_ap_cb(&data);
+}