qcacmn: Add MLME support for vdev delete all peer

Add umac/mlme support for vdev delete all
peer request which will replace individual peer
delete of peers under a vdev during vdev down.

Change-Id: I6afdfae619fce361acd60705fe2d7ad888a8e33e
CRs-Fixed: 2456858
diff --git a/umac/mlme/include/wlan_vdev_mlme.h b/umac/mlme/include/wlan_vdev_mlme.h
index 2742582..d5e2ef3 100644
--- a/umac/mlme/include/wlan_vdev_mlme.h
+++ b/umac/mlme/include/wlan_vdev_mlme.h
@@ -438,6 +438,8 @@
  * @mlme_vdev_notify_start_state_exit:  callback to notify on vdev start
  *                                      start state exit
  * @mlme_vdev_is_newchan_no_cac:        callback to check CAC is required
+ * @mlme_vdev_ext_peer_delete_all_rsp:  callback to initiate actions for
+ *                                      vdev mlme peer delete all response
  */
 struct vdev_mlme_ops {
 	QDF_STATUS (*mlme_vdev_validate_basic_params)(
@@ -509,6 +511,9 @@
 				struct vdev_mlme_obj *vdev_mlme);
 	QDF_STATUS (*mlme_vdev_is_newchan_no_cac)(
 				struct vdev_mlme_obj *vdev_mlme);
+	QDF_STATUS (*mlme_vdev_ext_peer_delete_all_rsp)(
+				struct vdev_mlme_obj *vdev_mlme,
+				struct peer_delete_all_response *rsp);
 };
 
 #ifdef FEATURE_VDEV_RSP_WAKELOCK
diff --git a/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c b/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c
index fa3002c..70404a1 100644
--- a/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c
+++ b/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c
@@ -526,3 +526,41 @@
 
 	return tgt_vdev_mgr_set_custom_aggr_size_send(vdev_mlme, &param);
 }
+
+static QDF_STATUS vdev_mgr_peer_delete_all_param_update(
+				struct vdev_mlme_obj *mlme_obj,
+				struct peer_delete_all_params *param)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = mlme_obj->vdev;
+	if (!vdev) {
+		mlme_err("VDEV is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	param->vdev_id = wlan_vdev_get_id(vdev);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS vdev_mgr_peer_delete_all_send(struct vdev_mlme_obj *mlme_obj)
+{
+	QDF_STATUS status;
+	struct peer_delete_all_params param = {0};
+
+	if (!mlme_obj) {
+		mlme_err("Invalid input");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = vdev_mgr_peer_delete_all_param_update(mlme_obj, &param);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_err("Param Update Error: %d", status);
+		return status;
+	}
+
+	status = tgt_vdev_mgr_peer_delete_all_send(mlme_obj, &param);
+
+	return status;
+}
+
diff --git a/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h b/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h
index 9ce437d..06ba419 100644
--- a/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h
+++ b/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.h
@@ -229,5 +229,13 @@
 					   uint32_t *vdev_ids,
 					   uint32_t num_vdevs);
 
+/**
+ * vdev_mgr_peer_delete_all_send() – MLME API to send peer delete all request
+ * @mlme_obj: pointer to vdev_mlme_obj
+ *
+ * Return: QDF_STATUS - Success or Failure
+ */
+QDF_STATUS vdev_mgr_peer_delete_all_send(struct vdev_mlme_obj *mlme_obj);
+
 #endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */
 #endif /* __VDEV_MGR_OPS_H__ */
diff --git a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h
index 4cddb80..a237b58 100644
--- a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h
+++ b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_rx_defs.h
@@ -32,11 +32,13 @@
 #define RESTART_RESPONSE_BIT  0x2
 #define STOP_RESPONSE_BIT   0x3
 #define DELETE_RESPONSE_BIT 0x4
-#define RESPONSE_BIT_MAX DELETE_RESPONSE_BIT
+#define PEER_DELETE_ALL_RESPONSE_BIT 0x5
+#define RESPONSE_BIT_MAX PEER_DELETE_ALL_RESPONSE_BIT
 
 #define START_RESPONSE_TIMER 6000 /* 6 seconds */
 #define STOP_RESPONSE_TIMER  3000 /* 3 seconds */
 #define DELETE_RESPONSE_TIMER  3000 /* 3 seconds */
+#define PEER_DELETE_ALL_RESPONSE_TIMER 6000 /* 6 seconds */
 
 /**
  * struct vdev_response_timer - vdev mgmt response ops timer
@@ -92,4 +94,14 @@
 	uint8_t vdev_id;
 };
 
+/**
+ * struct peer_delete_all_response - peer delete all response structure
+ * @vdev_id: vdev id
+ * @status: FW status for vdev delete all peer request
+ */
+struct peer_delete_all_response {
+	uint8_t vdev_id;
+	uint8_t status;
+};
+
 #endif /* __WLAN_VDEV_MGR_TGT_IF_RX_DEFS_H__ */
diff --git a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h
index bb50fef..fda5343 100644
--- a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h
+++ b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_api.h
@@ -253,5 +253,16 @@
  */
 QDF_STATUS tgt_vdev_mgr_bcn_miss_offload_send(struct vdev_mlme_obj *mlme_obj);
 
+/**
+ * tgt_vdev_mgr_peer_delete_all_send() – API to send peer delete all request
+ * @mlme_obj: pointer to vdev_mlme_obj
+ * @param: pointer to peer_delete_all_params
+ *
+ * Return: QDF_STATUS - Success or Failure
+ */
+QDF_STATUS tgt_vdev_mgr_peer_delete_all_send(
+				struct vdev_mlme_obj *mlme_obj,
+				struct peer_delete_all_params *param);
+
 #endif /* CMN_VDEV_MGR_TGT_IF_ENABLE */
 #endif /* __WLAN_VDEV_MGR_TX_OPS_API_H__ */
diff --git a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h
index 71e1b9f..eaef5b8 100644
--- a/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h
+++ b/umac/mlme/vdev_mgr/dispatcher/inc/wlan_vdev_mgr_tgt_if_tx_defs.h
@@ -442,5 +442,13 @@
 	uint8_t vdev_id;
 };
 
+/**
+ * struct peer_delete_all_params - peer delete all request parameter
+ * @vdev_id: vdev id
+ */
+struct peer_delete_all_params {
+	uint8_t vdev_id;
+};
+
 #endif
 #endif /* __WLAN_VDEV_MGR_TX_OPS_DEFS_H__ */
diff --git a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c
index e00cb35..cfacf07 100644
--- a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c
+++ b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_rx_api.c
@@ -72,11 +72,6 @@
 	}
 
 	vdev_rsp = &vdev_mlme->vdev_rt;
-	if (!vdev_rsp) {
-		mlme_err("VDEV_%d: Invalid response", rsp->vdev_id);
-		goto tgt_vdev_mgr_start_response_handler_end;
-	}
-
 	tx_ops = target_if_vdev_mgr_get_tx_ops(psoc);
 	if (rsp->resp_type == RESTART_RESPONSE)
 		status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp,
@@ -127,11 +122,6 @@
 	}
 
 	vdev_rsp = &vdev_mlme->vdev_rt;
-	if (!vdev_rsp) {
-		mlme_err("VDEV_%d: Invalid response", rsp->vdev_id);
-		goto tgt_vdev_mgr_stop_response_handler_end;
-	}
-
 	tx_ops = target_if_vdev_mgr_get_tx_ops(psoc);
 	status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp,
 						 STOP_RESPONSE_BIT);
@@ -149,7 +139,7 @@
 	return status;
 }
 
-QDF_STATUS tgt_vdev_mgr_delete_response_handler(
+static QDF_STATUS tgt_vdev_mgr_delete_response_handler(
 					struct wlan_objmgr_psoc *psoc,
 					struct vdev_delete_response *rsp)
 {
@@ -179,11 +169,6 @@
 	}
 
 	vdev_rsp = &vdev_mlme->vdev_rt;
-	if (!vdev_rsp) {
-		mlme_err("VDEV_%d: Invalid response", rsp->vdev_id);
-		goto tgt_vdev_mgr_delete_response_handler_end;
-	}
-
 	tx_ops = target_if_vdev_mgr_get_tx_ops(psoc);
 	status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp,
 						 DELETE_RESPONSE_BIT);
@@ -203,6 +188,55 @@
 	return status;
 }
 
+static QDF_STATUS tgt_vdev_mgr_peer_delete_all_response_handler(
+					struct wlan_objmgr_psoc *psoc,
+					struct peer_delete_all_response *rsp)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct vdev_mlme_obj *vdev_mlme;
+	struct wlan_objmgr_vdev *vdev;
+	struct vdev_response_timer *vdev_rsp;
+	struct wlan_lmac_if_mlme_tx_ops *tx_ops;
+
+	if (!rsp || !psoc) {
+		mlme_err("Invalid input");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
+						    rsp->vdev_id,
+						    WLAN_VDEV_TARGET_IF_ID);
+	if (!vdev) {
+		mlme_err("VDEV is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
+	if (!vdev_mlme) {
+		mlme_err("VDEV_%d: VDEV_MLME is NULL", rsp->vdev_id);
+		goto tgt_vdev_mgr_peer_delete_all_response_handler_end;
+	}
+
+	vdev_rsp = &vdev_mlme->vdev_rt;
+	tx_ops = target_if_vdev_mgr_get_tx_ops(psoc);
+	status = tx_ops->vdev_mgr_rsp_timer_stop(vdev, vdev_rsp,
+						 PEER_DELETE_ALL_RESPONSE_BIT);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlme_err("VDEV_%d: Unexpected response", rsp->vdev_id);
+		goto tgt_vdev_mgr_peer_delete_all_response_handler_end;
+	}
+
+	if ((vdev_mlme->ops) &&
+	    vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp)
+		status = vdev_mlme->ops->mlme_vdev_ext_peer_delete_all_rsp(
+								vdev_mlme,
+								rsp);
+
+tgt_vdev_mgr_peer_delete_all_response_handler_end:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID);
+	return status;
+}
+
 static QDF_STATUS
 tgt_vdev_mgr_offload_bcn_tx_status_event_handler(uint32_t vdev_id,
 						 uint32_t tx_status)
@@ -272,6 +306,8 @@
 		tgt_vdev_mgr_stop_response_handler;
 	mlme_rx_ops->vdev_mgr_delete_response =
 		tgt_vdev_mgr_delete_response_handler;
+	mlme_rx_ops->vdev_mgr_peer_delete_all_response =
+		tgt_vdev_mgr_peer_delete_all_response_handler;
 	mlme_rx_ops->vdev_mgr_get_response_timer_info =
 		tgt_vdev_mgr_get_response_timer_info;
 
diff --git a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c
index a27b2e6..1344bc2 100644
--- a/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c
+++ b/umac/mlme/vdev_mgr/dispatcher/src/wlan_vdev_mgr_tgt_if_tx_api.c
@@ -575,3 +575,32 @@
 
 	return status;
 }
+
+QDF_STATUS tgt_vdev_mgr_peer_delete_all_send(
+				struct vdev_mlme_obj *mlme_obj,
+				struct peer_delete_all_params *param)
+{
+	QDF_STATUS status;
+	struct wlan_lmac_if_mlme_tx_ops *txops;
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t vdev_id;
+
+	if (!param) {
+		mlme_err("Invalid input");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	vdev = mlme_obj->vdev;
+	vdev_id = wlan_vdev_get_id(vdev);
+	txops = wlan_vdev_mlme_get_lmac_txops(vdev);
+	if (!txops || !txops->peer_delete_all_send) {
+		mlme_err("VDEV_%d: No Tx Ops", vdev_id);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	status = txops->peer_delete_all_send(vdev, param);
+	if (QDF_IS_STATUS_ERROR(status))
+		mlme_err("VDEV_%d: Tx Ops Error : %d", vdev_id, status);
+
+	return QDF_STATUS_SUCCESS;
+}