qcacmn: 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. User
space configs these APs to firmware when the DUT
starts up next time.

CRs-Fixed: 2425197
Change-Id: I3857d2a605baa2673af333a7a0412f1690b59769
diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h
index 892761a..52b02df 100644
--- a/qdf/inc/qdf_types.h
+++ b/qdf/inc/qdf_types.h
@@ -365,6 +365,7 @@
  * @QDF_MODULE_ID_CMN_MLME: CMN MLME module ID
  * @QDF_MODULE_ID_CFR: CFR module ID
  * @QDF_MODULE_ID_TX_CAPTURE: Tx capture enhancement feature ID
+ * @QDF_MODULE_ID_INTEROP_ISSUES_AP: interop issues ap module ID
  * @QDF_MODULE_ID_ANY: anything
  * @QDF_MODULE_ID_MAX: Max place holder module ID
  */
@@ -479,6 +480,7 @@
 	QDF_MODULE_ID_BSSCOLOR,
 	QDF_MODULE_ID_CFR,
 	QDF_MODULE_ID_TX_CAPTURE,
+	QDF_MODULE_ID_INTEROP_ISSUES_AP,
 	QDF_MODULE_ID_ANY,
 	QDF_MODULE_ID_MAX,
 } QDF_MODULE_ID;
diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c
index ff18667..942fadb 100644
--- a/qdf/linux/src/qdf_trace.c
+++ b/qdf/linux/src/qdf_trace.c
@@ -2893,6 +2893,7 @@
 	[QDF_MODULE_ID_BSSCOLOR] = {"BSSCOLOR"},
 	[QDF_MODULE_ID_CFR] = {"CFR"},
 	[QDF_MODULE_ID_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"},
+	[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"},
 	[QDF_MODULE_ID_ANY] = {"ANY"},
 };
 qdf_export_symbol(g_qdf_category_name);
@@ -3349,6 +3350,7 @@
 		[QDF_MODULE_ID_BSSCOLOR] = QDF_TRACE_LEVEL_ERROR,
 		[QDF_MODULE_ID_CFR] = QDF_TRACE_LEVEL_ERROR,
 		[QDF_MODULE_ID_TX_CAPTURE] = QDF_TRACE_LEVEL_NONE,
+		[QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE,
 		[QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO,
 	};
 
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index d80f6d9..1b6f8c4 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -270,6 +270,7 @@
  * @WLAN_UMAC_COMP_CP_STATS:      Control Plane Statistics
  * @WLAN_UMAC_COMP_ACTION_OUI:    ACTION OUI
  * @WLAN_UMAC_COMP_FWOL           FW Offload
+ * @WLAN_UMAC_COMP_INTEROP_ISSUES_AP       interop issues ap component
  * @WLAN_UMAC_COMP_ID_MAX:        Maximum components in UMAC
  *
  * This id is static.
@@ -307,6 +308,7 @@
 	WLAN_UMAC_COMP_ACTION_OUI         = 28,
 	WLAN_UMAC_COMP_FWOL               = 29,
 	WLAN_UMAC_COMP_CFR                = 30,
+	WLAN_UMAC_COMP_INTEROP_ISSUES_AP           = 31,
 	WLAN_UMAC_COMP_ID_MAX,
 };
 
diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
index d2f60ff..236f77b 100644
--- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
+++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h
@@ -235,6 +235,7 @@
  * @WLAN_CFR_ID:                CFG Capture method
  * @WLAN_VDEV_TARGET_IF_ID:     Target interface layer
  * @WLAN_RX_PKT_TAG_ID:         RX protocol tag operations
+ * @WLAN_INTEROP_ISSUES_AP_ID:           interop issues ap operation
  * @WLAN_REF_ID_MAX:            Max id used to generate ref count tracking array
  */
  /* New value added to the enum must also be reflected in function
@@ -292,6 +293,7 @@
 	WLAN_CFR_ID                = 48,
 	WLAN_VDEV_TARGET_IF_ID     = 49,
 	WLAN_RX_PKT_TAG_ID         = 50,
+	WLAN_INTEROP_ISSUES_AP_ID           = 51,
 	WLAN_REF_ID_MAX,
 } wlan_objmgr_ref_dbgid;
 
@@ -356,6 +358,7 @@
 					"WLAN_CFR_ID",
 					"WLAN_VDEV_TARGET_IF_ID",
 					"WLAN_RX_PKT_TAG_ID",
+					"WLAN_INTEROP_ISSUES_AP_ID",
 					"WLAN_REF_ID_MAX"};
 
 	return (char *)strings[id];
diff --git a/wmi/inc/wmi_unified_interop_issues_ap_api.h b/wmi/inc/wmi_unified_interop_issues_ap_api.h
new file mode 100644
index 0000000..a1d7198
--- /dev/null
+++ b/wmi/inc/wmi_unified_interop_issues_ap_api.h
@@ -0,0 +1,48 @@
+/*
+ * 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: Implement API's specific to interop issues ap component.
+ */
+
+#ifndef _WMI_UNIFIED_INTEROP_ISSUES_AP_API_H_
+#define _WMI_UNIFIED_INTEROP_ISSUES_AP_API_H_
+
+#include <wmi_unified_param.h>
+#include <wlan_interop_issues_ap_public_structs.h>
+
+/**
+ * wmi_extract_interop_issues_ap_ev_param() - extract info from event
+ * @wmi_handle: wmi handle
+ * @evt_buf: event buffer
+ * @param: pointer to interop issues ap event structure
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS
+wmi_extract_interop_issues_ap_ev_param(wmi_unified_t wmi_handle, void *evt_buf,
+				   struct wlan_interop_issues_ap_event *param);
+/**
+ * wmi_unified_set_rap_ps_cmd() - set interop issues ap for ps in fw
+ * @wmi_handle: wmi handle
+ * @rap: interop issues ap info
+ *
+ * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
+ */
+QDF_STATUS wmi_unified_set_rap_ps_cmd(wmi_unified_t wmi_handle,
+				      struct wlan_interop_issues_ap_info *rap);
+#endif
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index 689f0e6..123aa4f 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -4835,6 +4835,9 @@
 	wmi_vdev_get_mws_coex_tdm_state_eventid,
 	wmi_vdev_get_mws_coex_idrx_state_eventid,
 	wmi_vdev_get_mws_coex_antenna_sharing_state_eventid,
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+	wmi_pdev_interop_issues_ap_event_id,
+#endif
 	wmi_events_max,
 } wmi_conv_event_id;
 
diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h
index 026d6dc..e34c66e 100644
--- a/wmi/inc/wmi_unified_priv.h
+++ b/wmi/inc/wmi_unified_priv.h
@@ -60,6 +60,10 @@
 #include "wmi_unified_atf_param.h"
 #endif
 
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+#include <wlan_interop_issues_ap_public_structs.h>
+#endif
+
 #define WMI_UNIFIED_MAX_EVENT 0x100
 
 #ifdef WMI_EXT_DBG
@@ -1487,6 +1491,15 @@
 					struct p2p_set_mac_filter_evt *param);
 #endif
 
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+QDF_STATUS
+(*extract_interop_issues_ap_ev_param)(wmi_unified_t wmi_handle, void *evt_buf,
+				  struct wlan_interop_issues_ap_event *param);
+QDF_STATUS
+(*send_set_rap_ps_cmd)(wmi_unified_t wmi_handle,
+		       struct wlan_interop_issues_ap_info *interop_issues_ap);
+#endif
+
 QDF_STATUS (*extract_peer_sta_ps_statechange_ev)(wmi_unified_t wmi_handle,
 	void *evt_buf, wmi_host_peer_sta_ps_statechange_event *ev);
 
@@ -2166,6 +2179,15 @@
 }
 #endif
 
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+void wmi_interop_issues_ap_attach_tlv(wmi_unified_t wmi_handle);
+#else
+static inline void
+wmi_interop_issues_ap_attach_tlv(struct wmi_unified *wmi_handle)
+{
+}
+#endif
+
 #ifdef FEATURE_LFR_SUBNET_DETECTION
 void wmi_lfr_subnet_detection_attach_tlv(wmi_unified_t wmi_handle);
 #else
diff --git a/wmi/src/wmi_unified_interop_issues_ap_api.c b/wmi/src/wmi_unified_interop_issues_ap_api.c
new file mode 100644
index 0000000..f29bf00
--- /dev/null
+++ b/wmi/src/wmi_unified_interop_issues_ap_api.c
@@ -0,0 +1,41 @@
+/*
+ * 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: Implement API's specific to interop issues ap component.
+ */
+
+#include <wmi_unified_priv.h>
+#include <wmi_unified_interop_issues_ap_api.h>
+
+QDF_STATUS
+wmi_extract_interop_issues_ap_ev_param(wmi_unified_t wmi_handle, void *evt_buf,
+				    struct wlan_interop_issues_ap_event *param)
+{
+	if (wmi_handle->ops->extract_interop_issues_ap_ev_param)
+		return wmi_handle->ops->extract_interop_issues_ap_ev_param(
+						wmi_handle, evt_buf, param);
+	return QDF_STATUS_E_FAILURE;
+}
+
+QDF_STATUS wmi_unified_set_rap_ps_cmd(wmi_unified_t wmi_handle,
+				      struct wlan_interop_issues_ap_info *rap)
+{
+	if (wmi_handle->ops->send_set_rap_ps_cmd)
+		return wmi_handle->ops->send_set_rap_ps_cmd(wmi_handle, rap);
+	return QDF_STATUS_E_FAILURE;
+}
diff --git a/wmi/src/wmi_unified_interop_issues_ap_tlv.c b/wmi/src/wmi_unified_interop_issues_ap_tlv.c
new file mode 100644
index 0000000..2748238
--- /dev/null
+++ b/wmi/src/wmi_unified_interop_issues_ap_tlv.c
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#include <osdep.h>
+#include <wmi.h>
+#include <wmi_unified_priv.h>
+#include <wmi_unified_interop_issues_ap_api.h>
+
+/**
+ * extract_interop_issues_ap_ev_param_tlv() - extract info from event
+ * @wmi_handle: wmi handle
+ * @param evt_buf: pointer to event buffer
+ * @param param: Pointer to hold interop issues ap info
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS
+extract_interop_issues_ap_ev_param_tlv(wmi_unified_t wmi_handle, void *evt_buf,
+				     struct wlan_interop_issues_ap_event *data)
+{
+	wmi_pdev_rap_info_event_fixed_param *fixed_param;
+	WMI_PDEV_RAP_INFO_EVENTID_param_tlvs *param_buf =
+		(WMI_PDEV_RAP_INFO_EVENTID_param_tlvs *)evt_buf;
+
+	if (!param_buf) {
+		wmi_err_rl("Invalid param_buf");
+		return -EINVAL;
+	}
+
+	fixed_param = param_buf->fixed_param;
+	if (!fixed_param) {
+		wmi_err_rl("Invalid fixed_praram");
+		return -EINVAL;
+	}
+
+	if (fixed_param->type != WMI_ROGUE_AP_ON_STA_PS) {
+		wmi_err_rl("Invalid type");
+		return -EINVAL;
+	}
+
+	data->pdev_id = fixed_param->pdev_id;
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_param->bssid, data->rap_addr.bytes);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * send_set_rap_ps_cmd_tlv() - set interop issues ap mac address in fw
+ * @wmi_handle: wmi handle
+ * @rap: interop issues ap info
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+static QDF_STATUS
+send_set_rap_ps_cmd_tlv(wmi_unified_t wmi_handle,
+			struct wlan_interop_issues_ap_info *rap)
+{
+	wmi_pdev_set_rap_config_fixed_param *cmd;
+	wmi_pdev_set_rap_config_on_sta_ps_tlv_param *param;
+	uint8_t *buf_ptr;
+	wmi_buf_t buf;
+	uint32_t ret;
+	uint32_t len, count;
+	qdf_size_t i;
+
+	count = rap->count;
+	len  = sizeof(*cmd) + WMI_TLV_HDR_SIZE + sizeof(*param) * count;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_FAILURE;
+
+	buf_ptr = wmi_buf_data(buf);
+	cmd = (wmi_pdev_set_rap_config_fixed_param *)buf_ptr;
+
+	WMITLV_SET_HDR(&cmd->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_set_rap_config_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_set_rap_config_fixed_param));
+	cmd->pdev_id = wmi_handle->ops->convert_pdev_id_host_to_target(
+						      WMI_HOST_PDEV_ID_SOC);
+
+	cmd->type = WMI_ROGUE_AP_ON_STA_PS;
+	if (count)
+		cmd->sta_ps_detection_enabled = 1;
+	else
+		cmd->sta_ps_detection_enabled = 0;
+
+	buf_ptr += sizeof(*cmd);
+
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		  sizeof(wmi_pdev_set_rap_config_on_sta_ps_tlv_param) * count);
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	for (i = 0; i < count; i++) {
+		param = (wmi_pdev_set_rap_config_on_sta_ps_tlv_param *)buf_ptr;
+		WMITLV_SET_HDR(&param->tlv_header,
+		  WMITLV_TAG_STRUC_wmi_pdev_set_rap_config_on_sta_ps_tlv_param,
+		  WMITLV_GET_STRUCT_TLVLEN
+				(wmi_pdev_set_rap_config_on_sta_ps_tlv_param));
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(rap->rap_items[i].bytes,
+					   &param->bssid);
+		buf_ptr += sizeof(*param);
+	}
+
+	ret = wmi_unified_cmd_send(wmi_handle, buf, len,
+				   WMI_PDEV_SET_RAP_CONFIG_CMDID);
+	if (ret) {
+		wmi_buf_free(buf);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
+void wmi_interop_issues_ap_attach_tlv(wmi_unified_t wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->extract_interop_issues_ap_ev_param =
+					extract_interop_issues_ap_ev_param_tlv;
+	ops->send_set_rap_ps_cmd = send_set_rap_ps_cmd_tlv;
+}
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index f1d1f4e..47b4e10 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -12187,6 +12187,10 @@
 	event_ids[wmi_wlan_sar2_result_event_id] = WMI_SAR2_RESULT_EVENTID;
 	event_ids[wmi_esp_estimate_event_id] = WMI_ESP_ESTIMATE_EVENTID;
 	event_ids[wmi_roam_scan_stats_event_id] = WMI_ROAM_SCAN_STATS_EVENTID;
+#ifdef WLAN_FEATURE_INTEROP_ISSUES_AP
+	event_ids[wmi_pdev_interop_issues_ap_event_id] =
+						WMI_PDEV_RAP_INFO_EVENTID;
+#endif
 #ifdef AST_HKV1_WORKAROUND
 	event_ids[wmi_wds_peer_event_id] = WMI_WDS_PEER_EVENTID;
 #endif
@@ -12516,6 +12520,7 @@
 	wmi_ocb_attach_tlv(wmi_handle);
 	wmi_nan_attach_tlv(wmi_handle);
 	wmi_p2p_attach_tlv(wmi_handle);
+	wmi_interop_issues_ap_attach_tlv(wmi_handle);
 	wmi_roam_attach_tlv(wmi_handle);
 	wmi_concurrency_attach_tlv(wmi_handle);
 	wmi_pmo_attach_tlv(wmi_handle);