Sfoglia il codice sorgente

qcacld-3.0: Add check to avoid multiple deauth on ML disconn

Add a new API to check if ML peer state is ML_PEER_DISCONN_INITIATED
that indicates the link vdev has sent deauth frame to FW. If the
check is true, then do not send another deauth for assoc vdev
to avoid FW assert.

Change-Id: I97ae39fe8a31072f8e93af958a02435c3b411283
CRs-Fixed: 3303552
Gururaj Pandurangi 2 anni fa
parent
commit
dbb6e82ba6

+ 34 - 0
core/mac/src/pe/lim/lim_mlo.c

@@ -1158,3 +1158,37 @@ lim_get_frame_mlo_ie_len(struct pe_session *session)
 	else
 		return 0;
 }
+
+bool
+lim_is_ml_peer_state_disconn(struct mac_context *mac_ctx,
+			     struct pe_session *session,
+			     uint8_t *mac_addr)
+{
+	struct wlan_objmgr_peer *peer;
+	struct wlan_mlo_peer_context *ml_peer = NULL;
+	bool is_ml_peer_disconn = false;
+
+	peer = wlan_objmgr_get_peer_by_mac(mac_ctx->psoc, mac_addr,
+					   WLAN_LEGACY_MAC_ID);
+
+	if (!peer) {
+		pe_err("peer is NULL");
+		return is_ml_peer_disconn;
+	}
+
+	if ((session->opmode == QDF_STA_MODE) &&
+	     wlan_vdev_mlme_is_mlo_vdev(session->vdev))
+		ml_peer = peer->mlo_peer_ctx;
+
+	if (!ml_peer) {
+		pe_err("ML peer ctx not found");
+		goto end;
+	}
+
+	if (QDF_IS_STATUS_SUCCESS(wlan_mlo_peer_is_disconnect_progress(ml_peer)))
+		is_ml_peer_disconn = true;
+
+end:
+	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
+	return is_ml_peer_disconn;
+}

+ 21 - 0
core/mac/src/pe/lim/lim_mlo.h

@@ -322,6 +322,19 @@ uint16_t lim_get_frame_mlo_ie_len(struct pe_session *session);
 QDF_STATUS lim_store_mlo_ie_raw_info(uint8_t *ie, uint8_t *sta_prof_ie,
 				     uint32_t total_len,
 				     struct wlan_mlo_ie *mlo_ie);
+
+/**
+ * lim_is_ml_peer_state_disconn() - Check if ML peer state is
+ * ML_PEER_DISCONN_INITIATED
+ * @mac_ctx: pointer to mac_context
+ * @session: pointer to pe_session
+ * @mac_addr: peer mac address
+ *
+ * Return: True if state is ML_PEER_DISCONN_INITIATED, else False
+ */
+bool lim_is_ml_peer_state_disconn(struct mac_context *mac_ctx,
+				  struct pe_session *session,
+				  uint8_t *mac_addr);
 #else
 static inline void lim_mlo_notify_peer_disconn(struct pe_session *pe_session,
 					       tpDphHashNode sta_ds)
@@ -433,5 +446,13 @@ uint16_t lim_get_frame_mlo_ie_len(struct pe_session *session)
 {
 	return 0;
 }
+
+static inline
+bool lim_is_ml_peer_state_disconn(struct mac_context *mac_ctx,
+				  struct pe_session *session,
+				  uint8_t *mac_addr)
+{
+	return false;
+}
 #endif
 #endif

+ 12 - 1
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -4312,7 +4312,7 @@ lim_send_disassoc_mgmt_frame(struct mac_context *mac,
  * \param nReason Indicates the reason that need to be sent in the
  * Deauthenticate frame
  *
- * \param peeer address of the STA to which the frame is to be sent
+ * \param peer address of the STA to which the frame is to be sent
  *
  *
  */
@@ -4364,6 +4364,17 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
 				lim_send_deauth_cnf(mac);
 			return;
 		}
+	} else if (lim_is_ml_peer_state_disconn(mac, pe_session, peer)) {
+		/**
+		 * Check if deauth is already sent on link vdev and ML peer
+		 * state is moved to ML_PEER_DISCONN_INITIATED. In which case,
+		 * do not send deauth on assoc vdev as well. Issue deauth only
+		 * if this check fails.
+		 */
+		pe_debug("Deauth tx not required for vdev id %d",
+			 pe_session->vdev_id);
+		lim_send_deauth_cnf(mac);
+		return;
 	}
 	smeSessionId = pe_session->smeSessionId;