qcacmn: Add blacklist manager related files

Add interface API to send reject ap list to FW,
also add the blacklist manager UMAC, and QDF component
for the same.

Change-Id: I826e537683441762043003d71dc2b79ceebebbcb
CRs-Fixed: 2460770
diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h
index e731410..43dbc29 100644
--- a/os_if/linux/qca_vendor.h
+++ b/os_if/linux/qca_vendor.h
@@ -2642,6 +2642,8 @@
  *	set bssid params num bssid
  * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID:
  *	set bssid params bssid
+ * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT:
+ *	flag attribute to specify whether the AP is avoided, or blacklisted.
  * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST: After last
  * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX: Max
  */
@@ -2673,6 +2675,7 @@
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18,
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19,
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20,
+	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT = 21,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST,
diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h
index 52b02df..886a509 100644
--- a/qdf/inc/qdf_types.h
+++ b/qdf/inc/qdf_types.h
@@ -366,6 +366,7 @@
  * @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_BLACKLIST_MGR: Blacklist Manager module
  * @QDF_MODULE_ID_ANY: anything
  * @QDF_MODULE_ID_MAX: Max place holder module ID
  */
@@ -481,6 +482,7 @@
 	QDF_MODULE_ID_CFR,
 	QDF_MODULE_ID_TX_CAPTURE,
 	QDF_MODULE_ID_INTEROP_ISSUES_AP,
+	QDF_MODULE_ID_BLACKLIST_MGR,
 	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 4239147..b2f7e98 100644
--- a/qdf/linux/src/qdf_trace.c
+++ b/qdf/linux/src/qdf_trace.c
@@ -2709,6 +2709,7 @@
 	[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_BLACKLIST_MGR] = {"blm"},
 	[QDF_MODULE_ID_ANY] = {"ANY"},
 };
 qdf_export_symbol(g_qdf_category_name);
@@ -3166,6 +3167,7 @@
 		[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_BLACKLIST_MGR] = 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 1b6f8c4..fa0b241 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -271,6 +271,7 @@
  * @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_BLACKLIST_MGR:      Blacklist mgr component
  * @WLAN_UMAC_COMP_ID_MAX:        Maximum components in UMAC
  *
  * This id is static.
@@ -308,7 +309,8 @@
 	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_INTEROP_ISSUES_AP  = 31,
+	WLAN_UMAC_COMP_BLACKLIST_MGR      = 32,
 	WLAN_UMAC_COMP_ID_MAX,
 };
 
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index 0404352..7889281 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -5310,6 +5310,7 @@
 	wmi_service_wpa3_ft_suite_b_support,
 	wmi_service_ft_fils,
 	wmi_service_adaptive_11r_support,
+	wmi_service_data_stall_recovery_support,
 	wmi_service_tx_compl_tsf64,
 	wmi_services_max,
 } wmi_conv_service_ids;
diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h
index e34c66e..6d45d8d 100644
--- a/wmi/inc/wmi_unified_priv.h
+++ b/wmi/inc/wmi_unified_priv.h
@@ -352,6 +352,12 @@
 				uint8_t mac_id);
 #endif
 
+#ifdef FEATURE_BLACKLIST_MGR
+QDF_STATUS
+(*send_reject_ap_list_cmd)(struct wmi_unified *wmi_handle,
+			   struct reject_ap_params *reject_params);
+#endif
+
 QDF_STATUS (*send_wow_enable_cmd)(wmi_unified_t wmi_handle,
 				struct wow_cmd_params *param,
 				uint8_t mac_id);
@@ -2322,6 +2328,15 @@
 }
 #endif
 
+#ifdef FEATURE_BLACKLIST_MGR
+void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle);
+#else
+static inline
+void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle)
+{
+}
+#endif
+
 #ifdef WMI_STA_SUPPORT
 void wmi_sta_attach_tlv(struct wmi_unified *wmi_handle);
 #else
diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h
index 8997500..c63f284 100644
--- a/wmi/inc/wmi_unified_roam_param.h
+++ b/wmi/inc/wmi_unified_roam_param.h
@@ -23,6 +23,8 @@
 #ifndef _WMI_UNIFIED_ROAM_PARAM_H_
 #define _WMI_UNIFIED_ROAM_PARAM_H_
 
+#include <wlan_blm_public_struct.h>
+
 /**
  * struct gateway_update_req_param - gateway parameter update request
  * @request_id: request id
@@ -168,19 +170,6 @@
 #define MAX_SSID_ALLOWED_LIST    4
 #define MAX_BSSID_AVOID_LIST     16
 #define MAX_BSSID_FAVORED      16
-#define MAX_RSSI_AVOID_BSSID_LIST 10
-
-/**
- * struct rssi_disallow_bssid - Structure holding Rssi based avoid candidate
- * @bssid: BSSID of the AP
- * @remaining_duration: remaining disallow duration in ms
- * @expected_rssi: RSSI at which STA can initate in dBm
- */
-struct rssi_disallow_bssid {
-	struct qdf_mac_addr bssid;
-	uint32_t remaining_duration;
-	int8_t expected_rssi;
-};
 
 /**
  * struct roam_scan_filter_params - Structure holding roaming scan
@@ -228,7 +217,8 @@
 	uint32_t rssi_channel_penalization;
 	uint32_t num_disallowed_aps;
 	uint32_t num_rssi_rejection_ap;
-	struct rssi_disallow_bssid rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST];
+	struct reject_ap_config_params
+				rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST];
 };
 
 #define WMI_CFG_VALID_CHANNEL_LIST_LEN    100
@@ -534,6 +524,7 @@
  * @frame_len: frame length, includs mac header, fixed params and ies
  * @frame_buf: buffer contaning probe response or beacon
  * @is_same_bssid: flag to indicate if roaming is requested for same bssid
+ * @forced_roaming: Roam to any bssid in any ch (here bssid & ch is not given)
  */
 struct wmi_roam_invoke_cmd {
 	uint32_t vdev_id;
@@ -542,6 +533,7 @@
 	uint32_t frame_len;
 	uint8_t *frame_buf;
 	uint8_t is_same_bssid;
+	bool forced_roaming;
 };
 
 /**
diff --git a/wmi/inc/wmi_unified_sta_api.h b/wmi/inc/wmi_unified_sta_api.h
index f40db70..9cecbae 100644
--- a/wmi/inc/wmi_unified_sta_api.h
+++ b/wmi/inc/wmi_unified_sta_api.h
@@ -96,6 +96,20 @@
 			struct disa_encrypt_decrypt_resp_params *resp);
 #endif /* WLAN_FEATURE_DISA */
 
+#ifdef FEATURE_BLACKLIST_MGR
+/**
+ * wmi_unified_send_reject_ap_list() - send the reject ap list maintained by
+ * BLM to FW for roaming cases.
+ * @wmi_handle: wmi handle
+ * @reject_params: This contains the reject ap list, and the num of BSSIDs.
+ *
+ * Return: QDF_STATUS_SUCCESS for success or error code
+ */
+QDF_STATUS
+wmi_unified_send_reject_ap_list(struct wmi_unified *wmi_handle,
+				struct reject_ap_params *reject_params);
+#endif
+
 /**
  * wmi_unified_process_dhcp_ind() - process dhcp indication from SME
  * @wmi_handle: wmi handle
diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c
index 86f9f27..99bd63e 100644
--- a/wmi/src/wmi_unified_roam_tlv.c
+++ b/wmi/src/wmi_unified_roam_tlv.c
@@ -511,7 +511,7 @@
 			roam_req->rssi_rejection_ap[i].bssid.bytes,
 			&rssi_rej->bssid);
 		rssi_rej->remaining_disallow_duration =
-			roam_req->rssi_rejection_ap[i].remaining_duration;
+			roam_req->rssi_rejection_ap[i].reject_duration;
 		rssi_rej->requested_rssi =
 			(int32_t)roam_req->rssi_rejection_ap[i].expected_rssi;
 		buf_ptr +=
@@ -836,7 +836,6 @@
 	wmi_mac_addr *bssid_list;
 	wmi_tlv_buf_len_param *buf_len_tlv;
 
-	/* Host sends only one channel and one bssid */
 	args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) +
 			sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) +
 			roundup(roaminvoke->frame_len, sizeof(uint32_t));
@@ -871,6 +870,12 @@
 	cmd->num_chan = 1;
 	cmd->num_bssid = 1;
 
+	if (roaminvoke->forced_roaming) {
+		cmd->num_chan = 0;
+		cmd->num_bssid = 0;
+		cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP;
+	}
+
 	buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param);
 	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32,
 		       (sizeof(u_int32_t)));
diff --git a/wmi/src/wmi_unified_sta_api.c b/wmi/src/wmi_unified_sta_api.c
index 98a9985..9585dd8 100644
--- a/wmi/src/wmi_unified_sta_api.c
+++ b/wmi/src/wmi_unified_sta_api.c
@@ -223,6 +223,19 @@
 }
 #endif /* WLAN_FEATURE_DISA */
 
+#ifdef FEATURE_BLACKLIST_MGR
+QDF_STATUS
+wmi_unified_send_reject_ap_list(struct wmi_unified *wmi_handle,
+				struct reject_ap_params *reject_params)
+{
+	if (wmi_handle->ops->send_reject_ap_list_cmd)
+		return wmi_handle->ops->send_reject_ap_list_cmd(wmi_handle,
+								reject_params);
+
+	return QDF_STATUS_E_FAILURE;
+}
+#endif
+
 QDF_STATUS wmi_unified_send_sar_limit_cmd(void *wmi_hdl,
 				struct sar_limit_cmd_params *params)
 {
diff --git a/wmi/src/wmi_unified_sta_tlv.c b/wmi/src/wmi_unified_sta_tlv.c
index 4c9e3fc..dfcfbc0 100644
--- a/wmi/src/wmi_unified_sta_tlv.c
+++ b/wmi/src/wmi_unified_sta_tlv.c
@@ -1088,6 +1088,107 @@
 	return 0;
 }
 
+#ifdef FEATURE_BLACKLIST_MGR
+
+static WMI_BSSID_DISALLOW_LIST_TYPE
+wmi_get_wmi_reject_ap_type(enum blm_reject_ap_type reject_ap_type)
+{
+	switch (reject_ap_type) {
+	case USERSPACE_AVOID_TYPE:
+		return WMI_BSSID_DISALLOW_USER_SPACE_AVOID_LIST;
+	case DRIVER_AVOID_TYPE:
+		return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
+	case USERSPACE_BLACKLIST_TYPE:
+		return WMI_BSSID_DISALLOW_USER_SPACE_BLACK_LIST;
+	case DRIVER_BLACKLIST_TYPE:
+		return WMI_BSSID_DISALLOW_DRIVER_BLACK_LIST;
+	case DRIVER_RSSI_REJECT_TYPE:
+		return WMI_BSSID_DISALLOW_RSSI_REJECT_LIST;
+	default:
+		return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST;
+	}
+}
+
+static QDF_STATUS
+send_reject_ap_list_cmd_tlv(wmi_unified_t wmi_handle,
+			    struct reject_ap_params *reject_params)
+{
+	wmi_buf_t buf;
+	QDF_STATUS status;
+	uint32_t len, list_tlv_len;
+	int i;
+	uint8_t *buf_ptr;
+	wmi_pdev_dsm_filter_fixed_param *chan_list_fp;
+	wmi_pdev_bssid_disallow_list_config_param *chan_list;
+	struct reject_ap_config_params *reject_list = reject_params->bssid_list;
+	uint8_t num_of_reject_bssid = reject_params->num_of_reject_bssid;
+
+	if (!num_of_reject_bssid) {
+		WMI_LOGD("%s : invalid number of channels %d", __func__,
+			 num_of_reject_bssid);
+		return QDF_STATUS_E_EMPTY;
+	}
+
+	list_tlv_len = sizeof(*chan_list) * num_of_reject_bssid;
+
+	len = sizeof(*chan_list_fp) + list_tlv_len + WMI_TLV_HDR_SIZE;
+	buf = wmi_buf_alloc(wmi_handle, len);
+	if (!buf)
+		return QDF_STATUS_E_NOMEM;
+
+	WMI_LOGD("num of reject BSSIDs %d", num_of_reject_bssid);
+
+	buf_ptr = (uint8_t *)wmi_buf_data(buf);
+	chan_list_fp = (wmi_pdev_dsm_filter_fixed_param *)buf_ptr;
+	WMITLV_SET_HDR(&chan_list_fp->tlv_header,
+		       WMITLV_TAG_STRUC_wmi_pdev_dsm_filter_fixed_param,
+		       WMITLV_GET_STRUCT_TLVLEN
+			       (wmi_pdev_dsm_filter_fixed_param));
+
+	buf_ptr += sizeof(wmi_pdev_dsm_filter_fixed_param);
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, list_tlv_len);
+
+	buf_ptr += WMI_TLV_HDR_SIZE;
+	chan_list = (wmi_pdev_bssid_disallow_list_config_param *)buf_ptr;
+	for (i = 0; i < num_of_reject_bssid; i++) {
+
+		WMITLV_SET_HDR(&chan_list->tlv_header,
+		     WMITLV_TAG_STRUC_wmi_pdev_bssid_disallow_list_config_param,
+			       WMITLV_GET_STRUCT_TLVLEN
+				  (wmi_pdev_bssid_disallow_list_config_param));
+		WMI_CHAR_ARRAY_TO_MAC_ADDR(reject_list[i].bssid.bytes,
+					   &chan_list->bssid);
+		chan_list->bssid_type =
+		    wmi_get_wmi_reject_ap_type(reject_list[i].reject_ap_type);
+		chan_list->expected_rssi = reject_list[i].expected_rssi;
+		chan_list->remaining_disallow_duration =
+					reject_list[i].reject_duration;
+		chan_list++;
+	}
+
+	wmi_mtrace(WMI_PDEV_DSM_FILTER_CMDID, NO_SESSION, 0);
+	status = wmi_unified_cmd_send(wmi_handle, buf,
+				      len, WMI_PDEV_DSM_FILTER_CMDID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_DSM_FILTER_CMDID returned Error %d",
+			 status);
+		goto error;
+	}
+
+	return QDF_STATUS_SUCCESS;
+error:
+	wmi_buf_free(buf);
+	return status;
+}
+
+void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle)
+{
+	struct wmi_ops *ops = wmi_handle->ops;
+
+	ops->send_reject_ap_list_cmd = send_reject_ap_list_cmd_tlv;
+}
+#endif
+
 #ifdef WLAN_FEATURE_DISA
 /**
  * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw
@@ -2498,5 +2599,6 @@
 	wmi_tdls_attach_tlv(wmi_handle);
 	wmi_disa_attach_tlv(wmi_handle);
 	wmi_policy_mgr_attach_tlv(wmi_handle);
+	wmi_blacklist_mgr_attach_tlv(wmi_handle);
 }
 
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index 47b4e10..b5648b3 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -12476,6 +12476,8 @@
 			WMI_SERVICE_ADAPTIVE_11R_ROAM;
 	wmi_service[wmi_service_tx_compl_tsf64] =
 			WMI_SERVICE_TX_COMPL_TSF64;
+	wmi_service[wmi_service_data_stall_recovery_support] =
+			WMI_SERVICE_DSM_ROAM_FILTER;
 }
 
 /**