qcacmn: Enable AST workaround only for HKV1

HKV1 does not have support to maintain per pdev AST table.
Hence workaround is required to ensure that AST entry is deleted before
adding an entry with same MAC. This syncronization needs to done across
pdev. This workaround in required on for HKV1, add changes to enable
workaround only for HKV1 and disabled for other platforms.

Change-Id: I9aa43ea51fdff2f02cdcc8ff7e906c7305446317
CRs-Fixed: 2344921
diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c
index 117f4d7..712efd0 100644
--- a/dp/wifi3.0/dp_main.c
+++ b/dp/wifi3.0/dp_main.c
@@ -723,8 +723,9 @@
 	bool wmi_sent = false;
 
 	qdf_spin_lock_bh(&soc->ast_lock);
-	wmi_sent = dp_peer_ast_get_wmi_sent(soc,
-					    (struct dp_ast_entry *)ast_entry);
+	wmi_sent = dp_peer_ast_get_del_cmd_sent(soc,
+						(struct dp_ast_entry *)
+						ast_entry);
 	qdf_spin_unlock_bh(&soc->ast_lock);
 
 	return wmi_sent;
@@ -951,7 +952,7 @@
 							" ast_hash = %d"
 							" pdev_id = %d"
 							" vdev_id = %d"
-							" wmi_sent = %d",
+							" del_cmd_sent = %d",
 							++num_entries,
 							ase->mac_addr.raw,
 							ase->peer->mac_addr.raw,
@@ -963,7 +964,7 @@
 							ase->ast_hash_value,
 							ase->pdev_id,
 							ase->vdev_id,
-							ase->wmi_sent);
+							ase->del_cmd_sent);
 				}
 			}
 		}
@@ -4071,7 +4072,8 @@
 }
 #endif
 
-#if defined(FEATURE_AST) && !defined(AST_HKV1_WORKAROUND)
+#if defined(FEATURE_AST)
+#if !defined(AST_HKV1_WORKAROUND)
 static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc,
 					       uint8_t *peer_mac_addr)
 {
@@ -4087,6 +4089,21 @@
 static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc,
 					       uint8_t *peer_mac_addr)
 {
+	struct dp_ast_entry *ast_entry;
+
+	if (soc->ast_override_support) {
+		qdf_spin_lock_bh(&soc->ast_lock);
+		ast_entry = dp_peer_ast_hash_find_soc(soc, peer_mac_addr);
+		if (ast_entry && ast_entry->next_hop)
+			dp_peer_del_ast(soc, ast_entry);
+		qdf_spin_unlock_bh(&soc->ast_lock);
+	}
+}
+#endif
+#else
+static inline void dp_peer_ast_handle_roam_del(struct dp_soc *soc,
+					       uint8_t *peer_mac_addr)
+{
 }
 #endif
 
diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c
index 5afe6ee..7041cae 100644
--- a/dp/wifi3.0/dp_peer.c
+++ b/dp/wifi3.0/dp_peer.c
@@ -485,6 +485,18 @@
 	return;
 }
 
+#ifdef AST_HKV1_WORKAROUND
+static inline void
+dp_peer_ast_init_del_cmd_sent_flag(struct dp_ast_entry *ast_entry)
+{
+	ast_entry->del_cmd_sent = false;
+}
+#else
+static inline void
+dp_peer_ast_init_del_cmd_sent_flag(struct dp_ast_entry *ast_entry)
+{}
+#endif
+
 /*
  * dp_peer_add_ast() - Allocate and add AST entry into peer list
  * @soc: SoC handle
@@ -609,6 +621,7 @@
 	ast_entry->pdev_id = vdev->pdev->pdev_id;
 	ast_entry->vdev_id = vdev->vdev_id;
 	ast_entry->is_mapped = false;
+	dp_peer_ast_init_del_cmd_sent_flag(ast_entry);
 
 	switch (type) {
 	case CDP_TXRX_AST_TYPE_STATIC:
@@ -695,14 +708,23 @@
 	if (ast_entry->next_hop &&
 	    ast_entry->type != CDP_TXRX_AST_TYPE_WDS_HM_SEC) {
 		dp_peer_ast_send_wds_del(soc, ast_entry);
-	} else {
+	}
+	/* AST free happens in completion handler for HKV1 */
+	if (soc->ast_override_support || !ast_entry->del_cmd_sent) {
 		/*
 		 * release the reference only if it is mapped
 		 * to ast_table
 		 */
 		if (ast_entry->is_mapped)
 			soc->ast_table[ast_entry->ast_idx] = NULL;
-		TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
+
+		/* ast_entry like next_hop is already removed as part of
+		 * AST del command send, Remove ast_entry that dont
+		 * send ast del command.
+		 */
+		if (!ast_entry->del_cmd_sent)
+			TAILQ_REMOVE(&peer->ast_entry_list, ast_entry,
+				     ase_list_elem);
 
 		if (ast_entry == peer->self_ast_entry)
 			peer->self_ast_entry = NULL;
@@ -939,18 +961,18 @@
 	struct dp_peer *peer = ast_entry->peer;
 	struct cdp_soc_t *cdp_soc = &soc->cdp_soc;
 
-	if (!ast_entry->wmi_sent) {
+	if (!ast_entry->del_cmd_sent) {
 		cdp_soc->ol_ops->peer_del_wds_entry(peer->vdev->osif_vdev,
 						    ast_entry->mac_addr.raw);
-		ast_entry->wmi_sent = true;
+		ast_entry->del_cmd_sent = true;
 		TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem);
 	}
 }
 
-bool dp_peer_ast_get_wmi_sent(struct dp_soc *soc,
-			      struct dp_ast_entry *ast_entry)
+bool dp_peer_ast_get_del_cmd_sent(struct dp_soc *soc,
+				  struct dp_ast_entry *ast_entry)
 {
-	return ast_entry->wmi_sent;
+	return ast_entry->del_cmd_sent;
 }
 
 void dp_peer_ast_free_entry(struct dp_soc *soc,
diff --git a/dp/wifi3.0/dp_peer.h b/dp/wifi3.0/dp_peer.h
index c3da59f..8d8d28e 100644
--- a/dp/wifi3.0/dp_peer.h
+++ b/dp/wifi3.0/dp_peer.h
@@ -145,8 +145,8 @@
 void dp_peer_ast_send_wds_del(struct dp_soc *soc,
 			      struct dp_ast_entry *ast_entry);
 
-bool dp_peer_ast_get_wmi_sent(struct dp_soc *soc,
-			      struct dp_ast_entry *ast_entry);
+bool dp_peer_ast_get_del_cmd_sent(struct dp_soc *soc,
+				  struct dp_ast_entry *ast_entry);
 
 void dp_peer_ast_free_entry(struct dp_soc *soc,
 			    struct dp_ast_entry *ast_entry);
diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h
index 990fc76..5053e3a 100644
--- a/dp/wifi3.0/dp_types.h
+++ b/dp/wifi3.0/dp_types.h
@@ -655,7 +655,7 @@
  * @ast_hash_value: hast value in HW
  * @ref_cnt: reference count
  * @type: flag to indicate type of the entry(static/WDS/MEC)
- * @wmi_sent: Flag to identify of WMI to del ast is sent (AST_HKV1_WORKAROUND)
+ * @del_cmd_sent: Flag to identify if WMI to del ast is sent
  * @cp_ctx: Opaque context used by control path (AST_HKV1_WORKAROUND)
  * @hash_list_elem: node in soc AST hash list (mac address used as hash)
  */
@@ -673,7 +673,7 @@
 	uint16_t ast_hash_value;
 	qdf_atomic_t ref_cnt;
 	enum cdp_txrx_ast_entry_type type;
-	bool wmi_sent;
+	bool del_cmd_sent;
 	void *cp_ctx;
 	TAILQ_ENTRY(dp_ast_entry) ase_list_elem;
 	TAILQ_ENTRY(dp_ast_entry) hash_list_elem;