Bladeren bron

qcacld-3.0: Wait for peer delete response from firmware

Currently driver does not wait for peer del response from firmware,
but posts del sta response indication to SME immediately. This
can cause an assert in firmware if driver receives add sta
immediately before even del sta response from firmware. Add
changes to wait for peer del response from firmware to fix
this.

Change-Id: I16a84256f4a1ed971c17eb3139faac5622eadda4
CRs-Fixed: 2008940
Padma, Santhosh Kumar 8 jaren geleden
bovenliggende
commit
4eb7908901

+ 7 - 0
core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c

@@ -1990,6 +1990,13 @@ void lim_process_sta_mlm_del_sta_rsp(tpAniSirGlobal pMac,
 	lim_log(pMac, LOG1, FL("Del STA RSP received. Status:%d AssocID:%d"),
 			pDelStaParams->status, pDelStaParams->assocId);
 
+#ifdef FEATURE_WLAN_TDLS
+	if (pDelStaParams->staType == STA_ENTRY_TDLS_PEER) {
+		lim_log(pMac, LOG1, FL("TDLS Del STA RSP received."));
+		lim_process_tdls_del_sta_rsp(pMac, limMsgQ, psessionEntry);
+		return;
+	}
+#endif
 	if (QDF_STATUS_SUCCESS != pDelStaParams->status)
 		lim_log(pMac, LOGE, FL(
 			"Del STA failed! Status:%d, proceeding with Del BSS"),

+ 74 - 25
core/mac/src/pe/lim/lim_process_tdls.c

@@ -2769,7 +2769,8 @@ static tSirRetStatus lim_tdls_setup_add_sta(tpAniSirGlobal pMac,
  */
 static tpDphHashNode lim_tdls_del_sta(tpAniSirGlobal pMac,
 				      struct qdf_mac_addr peerMac,
-				      tpPESession psessionEntry)
+				      tpPESession psessionEntry,
+				      bool resp_reqd)
 {
 	tSirRetStatus status = eSIR_SUCCESS;
 	uint16_t peerIdx = 0;
@@ -2783,11 +2784,13 @@ static tpDphHashNode lim_tdls_del_sta(tpAniSirGlobal pMac,
 		lim_log(pMac, LOG1, FL("DEL STA peer MAC: "MAC_ADDRESS_STR),
 		       MAC_ADDR_ARRAY(pStaDs->staAddr));
 
-		lim_log(pMac, LOG1, FL("STA type = %x, sta idx = %x"),
+		lim_log(pMac, LOG1,
+		       FL("STA type = %x, sta idx = %x resp_reqd %d"),
 		       pStaDs->staType,
-		       pStaDs->staIndex);
+		       pStaDs->staIndex,
+		       resp_reqd);
 
-		status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
+		status = lim_del_sta(pMac, pStaDs, resp_reqd, psessionEntry);
 	}
 
 	return pStaDs;
@@ -3151,7 +3154,6 @@ tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
 	tSirTdlsDelStaReq *pDelStaReq = (tSirTdlsDelStaReq *) pMsgBuf;
 	tpPESession psessionEntry;
 	uint8_t sessionId;
-	tpDphHashNode pStaDs = NULL;
 
 	lim_log(pMac, LOG1, FL("TDLS Delete STA Request Recieved"));
 	psessionEntry =
@@ -3190,25 +3192,8 @@ tSirRetStatus lim_process_sme_tdls_del_sta_req(tpAniSirGlobal pMac,
 		goto lim_tdls_del_sta_error;
 	}
 
-	pStaDs = lim_tdls_del_sta(pMac, pDelStaReq->peermac, psessionEntry);
-
-	/* now send indication to SME-->HDD->TL to remove STA from TL */
-
-	if (pStaDs) {
-		lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
-					      pDelStaReq->peermac, pStaDs,
-					      eSIR_SUCCESS);
-		lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
-
-		/* Clear the aid in peerAIDBitmap as this aid is now in freepool */
-		CLEAR_PEER_AID_BITMAP(psessionEntry->peerAIDBitmap,
-				      pStaDs->assocId);
-		lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
-					  psessionEntry);
-
-		return eSIR_SUCCESS;
-
-	}
+	lim_tdls_del_sta(pMac, pDelStaReq->peermac, psessionEntry, true);
+	return eSIR_SUCCESS;
 
 lim_tdls_del_sta_error:
 	lim_send_sme_tdls_del_sta_rsp(pMac, psessionEntry->smeSessionId,
@@ -3433,7 +3418,7 @@ tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
 						QDF_MAC_ADDR_SIZE);
 
 				lim_tdls_del_sta(mac_ctx, mac_addr,
-						session_entry);
+						session_entry, false);
 
 				dph_delete_hash_entry(mac_ctx,
 					stads->staAddr, stads->assocId,
@@ -3452,4 +3437,68 @@ tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
 	return eSIR_SUCCESS;
 }
 
+/**
+ * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS
+ * @mac_ctx: Global MAC context
+ * @lim_msg: LIM message
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+void lim_process_tdls_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				  struct scheduler_msg *lim_msg,
+				  tpPESession session_entry)
+{
+	tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
+	tpDphHashNode sta_ds;
+	uint16_t peer_idx = 0;
+	struct qdf_mac_addr peer_mac;
+
+	if (!del_sta_params) {
+		lim_log(mac_ctx, LOGE,
+			FL("del_sta_params is NULL"));
+		return;
+	}
+
+	sta_ds = dph_lookup_hash_entry(mac_ctx, del_sta_params->staMac,
+			&peer_idx, &session_entry->dph.dphHashTable);
+	if (!sta_ds) {
+		lim_log(mac_ctx, LOGE,
+			FL("DPH Entry for STA %X is missing."),
+			DPH_STA_HASH_INDEX_PEER);
+		goto skip_event;
+	}
+
+	qdf_mem_copy(peer_mac.bytes,
+			del_sta_params->staMac, QDF_MAC_ADDR_SIZE);
+
+	if (QDF_STATUS_SUCCESS != del_sta_params->status) {
+		lim_log(mac_ctx, LOGE, FL("DEL STA failed!"));
+		lim_send_sme_tdls_del_sta_rsp(mac_ctx,
+				      session_entry->smeSessionId,
+				      peer_mac, NULL, eSIR_FAILURE);
+		goto skip_event;
+	}
+
+	lim_log(mac_ctx, LOG1, FL("DEL STA success"));
+
+	/* now send indication to SME-->HDD->TL to remove STA from TL */
+
+	lim_send_sme_tdls_del_sta_rsp(mac_ctx, session_entry->smeSessionId,
+				      peer_mac, sta_ds,
+				      eSIR_SUCCESS);
+	lim_release_peer_idx(mac_ctx, sta_ds->assocId, session_entry);
+
+	/* Clear the aid in peerAIDBitmap as this aid is now in freepool */
+	CLEAR_PEER_AID_BITMAP(session_entry->peerAIDBitmap,
+			      sta_ds->assocId);
+	lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
+				  session_entry);
+
+skip_event:
+	qdf_mem_free(del_sta_params);
+	lim_msg->bodyptr = NULL;
+}
+
+
 #endif

+ 3 - 0
core/mac/src/pe/lim/lim_types.h

@@ -551,6 +551,9 @@ void lim_send_sme_mgmt_tx_completion(tpAniSirGlobal pMac, tpPESession psessionEn
 tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
 				    tpPESession session_entry);
 QDF_STATUS lim_process_tdls_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession);
+void lim_process_tdls_del_sta_rsp(tpAniSirGlobal mac_ctx,
+				  struct scheduler_msg *lim_msg,
+				  tpPESession session_entry);
 #else
 static inline tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
 						tpPESession session_entry)

+ 1 - 0
core/sme/src/common/sme_api.c

@@ -9939,6 +9939,7 @@ QDF_STATUS sme_update_tdls_peer_state(tHalHandle hHal,
 	case eSME_TDLS_PEER_STATE_TEARDOWN:
 		pTdlsPeerStateParams->peerState =
 			WMA_TDLS_PEER_STATE_TEARDOWN;
+		pTdlsPeerStateParams->resp_reqd = false;
 		break;
 
 	case eSME_TDLS_PEER_ADD_MAC_ADDR:

+ 1 - 0
core/wma/inc/wma_if.h

@@ -1238,6 +1238,7 @@ typedef struct sTdlsPeerStateParams {
 	tSirMacAddr peerMacAddr;
 	uint32_t peerState;
 	tTdlsPeerCapParams peerCap;
+	bool resp_reqd;
 } tTdlsPeerStateParams;
 
 /**

+ 44 - 2
core/wma/src/wma_dev_if.c

@@ -4131,6 +4131,8 @@ send_del_rsp:
 static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
 {
 	tTdlsPeerStateParams *peerStateParams;
+	struct wma_target_req *msg;
+	int status;
 
 	peerStateParams = qdf_mem_malloc(sizeof(tTdlsPeerStateParams));
 	if (!peerStateParams) {
@@ -4142,6 +4144,7 @@ static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
 
 	peerStateParams->peerState = WMA_TDLS_PEER_STATE_TEARDOWN;
 	peerStateParams->vdevId = del_sta->smesessionId;
+	peerStateParams->resp_reqd = del_sta->respReqd;
 	qdf_mem_copy(&peerStateParams->peerMacAddr,
 		     &del_sta->staMac, sizeof(tSirMacAddr));
 
@@ -4150,9 +4153,48 @@ static void wma_del_tdls_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
 		 __func__, peerStateParams->peerMacAddr,
 		 peerStateParams->peerState);
 
-	wma_update_tdls_peer_state(wma, peerStateParams);
+	status = wma_update_tdls_peer_state(wma, peerStateParams);
 
-	del_sta->status = QDF_STATUS_SUCCESS;
+	if (status < 0) {
+		WMA_LOGE("%s: wma_update_tdls_peer_state returned failure",
+				__func__);
+		goto send_del_rsp;
+	}
+
+	if (del_sta->respReqd &&
+			WMI_SERVICE_IS_ENABLED(wma->wmi_service_bitmap,
+				WMI_SERVICE_SYNC_DELETE_CMDS)) {
+		del_sta->status = QDF_STATUS_SUCCESS;
+		msg = wma_fill_hold_req(wma,
+				del_sta->smesessionId,
+				WMA_DELETE_STA_REQ,
+				WMA_DELETE_STA_RSP_START, del_sta,
+				WMA_DELETE_STA_TIMEOUT);
+		if (!msg) {
+			WMA_LOGP(FL("Failed to allocate vdev_id %d"),
+					peerStateParams->vdevId);
+			wma_remove_req(wma,
+					peerStateParams->vdevId,
+					WMA_DELETE_STA_RSP_START);
+			del_sta->status = QDF_STATUS_E_NOMEM;
+			goto send_del_rsp;
+		}
+		/*
+		 * Acquire wake lock and bus lock till
+		 * firmware sends the response
+		 */
+		cds_host_diag_log_work(&wma->
+				wmi_cmd_rsp_wake_lock,
+				WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION,
+				WIFI_POWER_EVENT_WAKELOCK_WMI_CMD_RSP);
+		qdf_wake_lock_timeout_acquire(&wma->
+				wmi_cmd_rsp_wake_lock,
+				WMA_FW_RSP_EVENT_WAKE_LOCK_DURATION);
+		qdf_runtime_pm_prevent_suspend(wma->
+				wmi_cmd_rsp_runtime_lock);
+	}
+
+	return;
 
 send_del_rsp:
 	if (del_sta->respReqd) {