qcacld-3.0: Fix freeing of SAP PE session lim_send_sme_disassoc_ntf

When a peer connected to a SAP session triggers disconnect,
lim_send_sme_disassoc_ntf is called with the reason
eLIM_PEER_ENTITY_DISASSOC. This leads to the PE sesssion for the SAP
being freed as part of the lim_send_disconnect_done_ind added in the
change Iec0176fecf218e07f31b258c0dc52aefb480defe.

Modify the lim_send_disconnect_done_ind API to just prepare the
disconnect done indication message and the calling function
lim_send_sme_disassoc_ntf would send the notification to SME and
free the PE session only if the current session is a STA.

Change-Id: I377f86f10becd467417d4c6409d167020e26fe87
CRs-Fixed: 2241899
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 0552e78..ebc4d67 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -2282,6 +2282,8 @@
 	tpDphHashNode pStaDs;
 	tpPESession psessionEntry;
 	uint8_t sessionId;
+	uint32_t *msg = NULL;
+	QDF_STATUS status;
 
 	qdf_mem_copy(&smeDisassocCnf, pMsgBuf,
 			sizeof(struct sSirSmeDisassocCnf));
@@ -2291,16 +2293,26 @@
 				&sessionId);
 	if (psessionEntry == NULL) {
 		pe_err("session does not exist for given bssId");
-		lim_send_disconnect_done_ind(pMac, NULL, CSR_SESSION_ID_INVALID,
-					     eSIR_SME_INVALID_SESSION, NULL);
+		status = lim_prepare_disconnect_done_ind(pMac, &msg,
+						CSR_SESSION_ID_INVALID,
+						eSIR_SME_INVALID_SESSION,
+						NULL);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
 		return;
 	}
 
 	if (!lim_is_sme_disassoc_cnf_valid(pMac, &smeDisassocCnf, psessionEntry)) {
 		pe_err("received invalid SME_DISASSOC_CNF message");
-		lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
-					     eSIR_SME_INVALID_PARAMETERS,
-					     smeDisassocCnf.bssid.bytes);
+		status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
+						eSIR_SME_INVALID_PARAMETERS,
+						&smeDisassocCnf.bssid.bytes[0]);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
 		return;
 	}
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
@@ -2324,11 +2336,15 @@
 				psessionEntry->limSmeState);
 			lim_print_sme_state(pMac, LOGE,
 					    psessionEntry->limSmeState);
-			lim_send_disconnect_done_ind(pMac, psessionEntry,
-						     sessionId,
-						     eSIR_SME_INVALID_STATE,
-						     smeDisassocCnf.bssid.
-						     bytes);
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
+							sessionId,
+							eSIR_SME_INVALID_STATE,
+							&smeDisassocCnf.bssid.
+							bytes[0]);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
 			return;
 		}
 		break;
@@ -2341,9 +2357,13 @@
 	default:                /* eLIM_UNKNOWN_ROLE */
 		pe_err("received unexpected SME_DISASSOC_CNF role %d",
 			GET_LIM_SYSTEM_ROLE(psessionEntry));
-		lim_send_disconnect_done_ind(pMac, psessionEntry, sessionId,
-					     eSIR_SME_INVALID_STATE,
-					     smeDisassocCnf.bssid.bytes);
+		status = lim_prepare_disconnect_done_ind(pMac, &msg, sessionId,
+						eSIR_SME_INVALID_STATE,
+						&smeDisassocCnf.bssid.bytes[0]);
+		if (QDF_IS_STATUS_SUCCESS(status))
+			lim_send_sme_disassoc_deauth_ntf(pMac,
+							 QDF_STATUS_SUCCESS,
+							 (uint32_t *)msg);
 		return;
 	}
 
@@ -2357,10 +2377,14 @@
 			pe_err("DISASSOC_CNF for a STA with no context, addr= "
 				MAC_ADDRESS_STR,
 				MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes));
-			lim_send_disconnect_done_ind(pMac, psessionEntry,
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
 						sessionId,
 						eSIR_SME_INVALID_PARAMETERS,
-						smeDisassocCnf.bssid.bytes);
+						&smeDisassocCnf.bssid.bytes[0]);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
 			return;
 		}
 
@@ -2371,9 +2395,14 @@
 			pe_err("No need of cleanup for addr:" MAC_ADDRESS_STR "as MLM state is %d",
 				MAC_ADDR_ARRAY(smeDisassocCnf.peer_macaddr.bytes),
 				pStaDs->mlmStaContext.mlmState);
-			lim_send_disconnect_done_ind(pMac, NULL,
-						     CSR_SESSION_ID_INVALID,
-						     eSIR_SME_SUCCESS, NULL);
+			status = lim_prepare_disconnect_done_ind(pMac, &msg,
+							CSR_SESSION_ID_INVALID,
+							eSIR_SME_SUCCESS,
+							NULL);
+			if (QDF_IS_STATUS_SUCCESS(status))
+				lim_send_sme_disassoc_deauth_ntf(pMac,
+							QDF_STATUS_SUCCESS,
+							(uint32_t *)msg);
 			return;
 		}
 
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
index 900dff8..aa9a7e4 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c
@@ -806,6 +806,7 @@
 	tpPESession session = NULL;
 	uint16_t i, assoc_id;
 	tpDphHashNode sta_ds = NULL;
+	QDF_STATUS status;
 
 	pe_debug("Disassoc Ntf with trigger : %d reasonCode: %d",
 		disassocTrigger, reasonCode);
@@ -893,9 +894,14 @@
 
 	case eLIM_PEER_ENTITY_DISASSOC:
 	case eLIM_LINK_MONITORING_DISASSOC:
-		lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
-					     reasonCode, peerMacAddr);
-		return;
+		status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+						smesessionId,
+						reasonCode, &peerMacAddr[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("Failed to prepare message");
+			return;
+		}
+		break;
 
 	default:
 		/**
@@ -1162,31 +1168,30 @@
 
 #endif /* FEATURE_WLAN_TDLS */
 
-void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
-				  tpPESession session_entry, uint8_t session_id,
-				  tSirResultCodes reason_code,
-				  tSirMacAddr peer_mac_addr)
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+					   uint32_t **msg,
+					   uint8_t session_id,
+					   tSirResultCodes reason_code,
+					   uint8_t *peer_mac_addr)
 {
 	struct sir_sme_discon_done_ind *sir_sme_dis_ind;
-	uint32_t *msg;
 
-	sir_sme_dis_ind =
-		qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
+	sir_sme_dis_ind = qdf_mem_malloc(sizeof(*sir_sme_dis_ind));
 	if (!sir_sme_dis_ind) {
-		pe_err("call to AllocateMemory failed for disconnect indication");
-		return;
+		pe_err("Failed to allocate memory");
+		return QDF_STATUS_E_FAILURE;
 	}
 
-	pe_debug("send eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
+	pe_debug("Prepare eWNI_SME_DISCONNECT_DONE_IND withretCode: %d",
 		 reason_code);
 
-	sir_sme_dis_ind->message_type =
-		eWNI_SME_DISCONNECT_DONE_IND;
-	sir_sme_dis_ind->length =
-		sizeof(*sir_sme_dis_ind);
+	sir_sme_dis_ind->message_type = eWNI_SME_DISCONNECT_DONE_IND;
+	sir_sme_dis_ind->length = sizeof(*sir_sme_dis_ind);
 	sir_sme_dis_ind->session_id = session_id;
-	qdf_mem_copy(sir_sme_dis_ind->peer_mac, peer_mac_addr,
-		     ETH_ALEN);
+	if (peer_mac_addr)
+		qdf_mem_copy(&sir_sme_dis_ind->peer_mac,
+			     &peer_mac_addr, ETH_ALEN);
+
 	/*
 	 * Instead of sending deauth reason code as 505 which is
 	 * internal value(eSIR_SME_LOST_LINK_WITH_PEER_RESULT_CODE)
@@ -1197,14 +1202,9 @@
 	else
 		sir_sme_dis_ind->reason_code = reason_code;
 
-	msg = (uint32_t *)sir_sme_dis_ind;
+	*msg = (uint32_t *)sir_sme_dis_ind;
 
-	/*Delete the PE session  created */
-	if (session_entry)
-		pe_delete_session(mac_ctx, session_entry);
-
-	lim_send_sme_disassoc_deauth_ntf(mac_ctx, QDF_STATUS_SUCCESS,
-					 (uint32_t *)msg);
+	return QDF_STATUS_SUCCESS;
 }
 
 /**
@@ -1245,7 +1245,8 @@
 	tSirSmeDeauthInd *pSirSmeDeauthInd;
 	tpPESession psessionEntry;
 	uint8_t sessionId;
-	uint32_t *pMsg;
+	uint32_t *pMsg = NULL;
+	QDF_STATUS status;
 
 	psessionEntry = pe_find_session_by_bssid(pMac, peerMacAddr, &sessionId);
 	switch (deauthTrigger) {
@@ -1281,9 +1282,14 @@
 
 	case eLIM_PEER_ENTITY_DEAUTH:
 	case eLIM_LINK_MONITORING_DEAUTH:
-		lim_send_disconnect_done_ind(pMac, psessionEntry, smesessionId,
-					     reasonCode, peerMacAddr);
-		return;
+		status = lim_prepare_disconnect_done_ind(pMac, &pMsg,
+						smesessionId, reasonCode,
+						&peerMacAddr[0]);
+		if (!QDF_IS_STATUS_SUCCESS(status)) {
+			pe_err("Failed to prepare message");
+			return;
+		}
+		break;
 	default:
 		/**
 		 * Deauthentication indication due to Deauthentication
diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
index a6b9f85..33ec586 100644
--- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
+++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h
@@ -44,10 +44,23 @@
 				tpPESession, uint8_t, uint16_t);
 void lim_send_sme_join_reassoc_rsp(tpAniSirGlobal, uint16_t, tSirResultCodes,
 				   uint16_t, tpPESession, uint8_t, uint16_t);
-void lim_send_disconnect_done_ind(tpAniSirGlobal mac_ctx,
-				  tpPESession session_entry, uint8_t session_id,
-				  tSirResultCodes reason_code,
-				  tSirMacAddr peer_mac_addr);
+
+/*
+ * lim_prepare_disconnect_done_ind() - Prepares the disconnect done ind message
+ * @mac_ctx: Global mac_ctx
+ * @session_id: PE session id
+ * @reason_code: Disconnect indication reason code
+ * @peer_mac_addr: MAC address of the peer
+ *
+ * Prepares the disconnect done indication message to be sent to the upper layer
+ *
+ * Return: QDF Status
+ */
+QDF_STATUS lim_prepare_disconnect_done_ind(tpAniSirGlobal mac_ctx,
+					   uint32_t **msg,
+					   uint8_t session_id,
+					   tSirResultCodes reason_code,
+					   uint8_t *peer_mac_addr);
 void lim_send_sme_disassoc_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes,
 			       uint16_t, uint16_t, uint8_t, uint16_t, tpPESession);
 void lim_send_sme_deauth_ntf(tpAniSirGlobal, tSirMacAddr, tSirResultCodes, uint16_t,