Browse Source

qcacld-3.0: Ignore deauth ind received when in DEAUTH_REQ substate

P2P GO received deauth frame from p2p client and del_station is
received from userspace. As part of del_station FORCE_DEAUTH_STA
command is processed. Deauth frame is processed after this which
sends DEAUTH_IND to csr. Wm status change command is enqueued and
is not processed since there is already an active command. Cleanup
is done as part of del_station. Auth frame received is processed
and auth rsp is sent. Message is posted to lim on receiving assoc
req frame from p2p client. Wm status change command is processed
and DEAUTH_CNF msg is posted to lim. Assoc req frame is processed
and ASSOC_CNF is posted to lim. DEAUTH_CNF is processed before
ASSOC_CNF due to which sta_ds entry is removed. Assoc resp is
not transmitted as a result and p2p group formation fails.

Fix is to ignore deauth indication received when csr substate
is DEAUTH_REQ.

Change-Id: Ia1966a4cced3faf15605aeb3d69b8fafa2176c22
CRs-Fixed: 2248136
Yeshwanth Sriram Guntuka 6 years ago
parent
commit
d8987cf5ec
1 changed files with 50 additions and 0 deletions
  1. 50 0
      core/sme/src/csr/csr_api_roam.c

+ 50 - 0
core/sme/src/csr/csr_api_roam.c

@@ -11710,6 +11710,46 @@ csr_roam_chk_lnk_assoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
 	}
 }
 
+/*
+ * csr_is_deauth_disassoc_already_active() - Function to check if deauth or
+ *  disassoc is already in progress.
+ * @mac_ctx: Global MAC context
+ * @session_id: session id
+ * @peer_macaddr: Peer MAC address
+ *
+ * Return: True if deauth/disassoc indication can be dropped
+ *  else false
+ */
+static bool csr_is_deauth_disassoc_already_active(tpAniSirGlobal mac_ctx,
+					       uint8_t session_id,
+					       struct qdf_mac_addr peer_macaddr)
+{
+	bool ret = false;
+	tSmeCmd *sme_cmd;
+
+	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, session_id,
+						 WLAN_SER_CMD_FORCE_DEAUTH_STA);
+	if (!sme_cmd) {
+		sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc,
+					       session_id,
+					       WLAN_SER_CMD_FORCE_DISASSOC_STA);
+		if (!sme_cmd)
+			return ret;
+	}
+
+	if ((mac_ctx->roam.curSubState[session_id] ==
+	     eCSR_ROAM_SUBSTATE_DEAUTH_REQ ||
+	     mac_ctx->roam.curSubState[session_id] ==
+	     eCSR_ROAM_SUBSTATE_DISASSOC_REQ) &&
+	    !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
+			 QDF_MAC_ADDR_SIZE)) {
+		sme_err("Ignore DEAUTH_IND/DIASSOC_IND as Deauth/Disassoc already in progress");
+		ret = true;
+	}
+
+	return ret;
+}
+
 static void
 csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
 {
@@ -11740,6 +11780,12 @@ csr_roam_chk_lnk_disassoc_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
 		return;
 	}
 
+	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
+	    pDisassocInd->peer_macaddr)) {
+		qdf_mem_free(cmd);
+		return;
+	}
+
 	sme_err("DISASSOCIATION from peer =" MAC_ADDRESS_STR "reason: %d status: %d session: %d",
 		MAC_ADDR_ARRAY(pDisassocInd->peer_macaddr.bytes),
 		pDisassocInd->reasonCode,
@@ -11872,6 +11918,10 @@ csr_roam_chk_lnk_deauth_ind(tpAniSirGlobal mac_ctx, tSirSmeRsp *msg_ptr)
 						   &sessionId);
 	if (!QDF_IS_STATUS_SUCCESS(status))
 		return;
+
+	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
+	    pDeauthInd->peer_macaddr))
+		return;
 	/* If we are in neighbor preauth done state then on receiving
 	 * disassoc or deauth we dont roam instead we just disassoc
 	 * from current ap and then go to disconnected state