Эх сурвалжийг харах

qcacld-3.0: Add MLD addr check for SAP Deauth/Disassoc

Currently, driver check peer mac address to filter out duplicate
command in serialization queue. This peer mac address will be
peer MLD address from North bound and link address from the south
bound. For multi-link SAP, if disassociation or deauthentication
request received for two links of same STA (MLD address is same but
link address is different), then driver queue disassociation or
deauthentication command in the serialization for both links.
This will lead to duplicate disassociation or DE authentication commands
in the serialization for same STA.

So, to fix this, add check for MLD address and link address in the
serialization filter.

Change-Id: I2619e3009b28ceba6af4383e36ae40af82020b5f
CRs-Fixed: 3790148
Rahul Gusain 1 жил өмнө
parent
commit
bd3752ec96

+ 26 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -100,6 +100,18 @@ enum wmm_user_mode {
 
 };
 
+/**
+ * struct peer_mac_addresses -Peer MAC address info
+ * @mac: Provided peer MAC address
+ * @peer_mac: Peer MAC address
+ * @peer_mld: Peer MLD address
+ */
+struct peer_mac_addresses {
+	struct qdf_mac_addr mac;
+	struct qdf_mac_addr peer_mac;
+	struct qdf_mac_addr peer_mld;
+};
+
 struct pwr_channel_info {
 	uint32_t first_freq;
 	uint8_t num_chan;
@@ -2007,4 +2019,18 @@ uint8_t wlan_mlme_get_sap_psd_for_20mhz(struct wlan_objmgr_vdev *vdev);
  */
 QDF_STATUS wlan_mlme_set_sap_psd_for_20mhz(struct wlan_objmgr_vdev *vdev,
 					   uint8_t psd_power);
+
+/**
+ * wlan_find_peer_and_get_mac_and_mld_addr() - This API find peer from the peer
+ * list and cache peer MAC and MLD address in the peer_mac_info.
+ * @psoc: PSOC object
+ * @peer_mac_info: Peer MAC address info
+ *
+ * Return: None
+ */
+QDF_STATUS
+wlan_find_peer_and_get_mac_and_mld_addr(
+				struct wlan_objmgr_psoc *psoc,
+				struct peer_mac_addresses *peer_mac_info);
+
 #endif

+ 65 - 0
components/mlme/core/src/wlan_mlme_main.c

@@ -5755,3 +5755,68 @@ wlan_mlme_set_sap_psd_for_20mhz(struct wlan_objmgr_vdev *vdev,
 	mlme_priv->mlme_ap.psd_20mhz = psd_power;
 	return QDF_STATUS_SUCCESS;
 }
+
+/**
+ * wlan_peer_find_mld_peer_n_get_mac_info() - This API will find MLD peer from
+ * peer list.
+ * @psoc: Pointer to psoc object
+ * @obj: Pointer to peer object
+ * @args: Pointer to void * argument
+ *
+ * Return: void
+ */
+static void
+wlan_peer_find_mld_peer_n_get_mac_info(struct wlan_objmgr_psoc *psoc,
+				       void *obj, void *args)
+{
+	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
+	struct peer_mac_addresses *peer_mac_info =
+				(struct peer_mac_addresses *)args;
+	uint8_t *mld_mac, *peer_mac, *given_mac;
+
+	mld_mac = wlan_peer_mlme_get_mldaddr(peer);
+	peer_mac = wlan_peer_get_macaddr(peer);
+	given_mac = peer_mac_info->mac.bytes;
+
+	if (!mld_mac || WLAN_ADDR_EQ(mld_mac, given_mac) != QDF_STATUS_SUCCESS)
+		return;
+	qdf_copy_macaddr(&peer_mac_info->peer_mac,
+			 (struct qdf_mac_addr *)peer_mac);
+	qdf_copy_macaddr(&peer_mac_info->peer_mld,
+			 (struct qdf_mac_addr *)mld_mac);
+}
+
+QDF_STATUS wlan_find_peer_and_get_mac_and_mld_addr(
+				struct wlan_objmgr_psoc *psoc,
+				struct peer_mac_addresses *peer_mac_info)
+{
+	struct wlan_objmgr_peer *peer;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac_info->mac.bytes,
+					   WLAN_LEGACY_MAC_ID);
+	if (peer) {
+		qdf_copy_macaddr(
+			&peer_mac_info->peer_mac,
+			(struct qdf_mac_addr *)wlan_peer_get_macaddr(peer));
+		if (wlan_peer_mlme_get_mldaddr(peer))
+			qdf_copy_macaddr(
+				&peer_mac_info->peer_mld,
+				(struct qdf_mac_addr *)
+				wlan_peer_mlme_get_mldaddr(peer));
+		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_MAC_ID);
+		return status;
+	}
+
+	/* if not found with mac address try finding using MLD address */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
+				     wlan_peer_find_mld_peer_n_get_mac_info,
+				     peer_mac_info, 0, WLAN_LEGACY_MAC_ID);
+	if (qdf_is_macaddr_zero(&peer_mac_info->peer_mac)) {
+		mlme_err("peer is null for mac:" QDF_MAC_ADDR_FMT,
+			 QDF_MAC_ADDR_REF(peer_mac_info->mac.bytes));
+		return QDF_STATUS_E_EXISTS;
+	}
+
+	return status;
+}

+ 2 - 0
core/mac/inc/sir_api.h

@@ -1191,6 +1191,7 @@ struct disassoc_ind {
 	tSirResultCodes status_code;
 	struct qdf_mac_addr bssid;
 	struct qdf_mac_addr peer_macaddr;
+	struct qdf_mac_addr peer_mld_addr;
 	uint16_t staId;
 	uint32_t reasonCode;
 	bool from_ap;
@@ -1262,6 +1263,7 @@ struct deauth_ind {
 	tSirResultCodes status_code;
 	struct qdf_mac_addr bssid;      /* AP BSSID */
 	struct qdf_mac_addr peer_macaddr;
+	struct qdf_mac_addr peer_mld_addr;
 
 	uint16_t staId;
 	uint32_t reasonCode;

+ 5 - 1
core/sme/inc/csr_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -35,6 +35,9 @@
 
 #define CSR_INVALID_SCANRESULT_HANDLE       (NULL)
 
+/* Length to print MAC 12 char + 5 ":" + 2 space + mld string */
+#define MAC_ADDR_DUMP_LEN 26
+
 enum csr_akm_type {
 	/* never used */
 	eCSR_AUTH_TYPE_NONE,
@@ -748,6 +751,7 @@ typedef struct tagCsrEseBeaconReq {
 
 struct csr_del_sta_params {
 	struct qdf_mac_addr peerMacAddr;
+	struct qdf_mac_addr peer_mld_addr;
 	uint16_t reason_code;
 	uint8_t subtype;
 };

+ 2 - 1
core/sme/inc/csr_internal.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -118,6 +118,7 @@ struct csr_channel {
 struct roam_cmd {
 	enum csr_roam_reason roamReason;
 	tSirMacAddr peerMac;
+	struct qdf_mac_addr peer_mld_addr;
 	enum wlan_reason_code reason;
 };
 

+ 26 - 4
core/sme/src/common/sme_api.c

@@ -564,28 +564,50 @@ static void sme_dump_peer_disconnect_timeout_info(tSmeCmd *sme_cmd)
 {
 	struct wmstatus_changecmd *wms_cmd;
 	struct qdf_mac_addr peer_macaddr = QDF_MAC_ADDR_ZERO_INIT;
+	struct qdf_mac_addr peer_mld_addr = QDF_MAC_ADDR_ZERO_INIT;
+	char mld_log_str[MAC_ADDR_DUMP_LEN] = {0};
 
 	if (sme_cmd->command == eSmeCommandRoam &&
 	    (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta ||
 	    sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta)) {
 		qdf_mem_copy(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
 			     QDF_MAC_ADDR_SIZE);
+		if (!qdf_is_macaddr_zero(&sme_cmd->u.roamCmd.peer_mld_addr))
+			qdf_copy_macaddr(&peer_mld_addr,
+					 &sme_cmd->u.roamCmd.peer_mld_addr);
 	} else if (sme_cmd->command == eSmeCommandWmStatusChange) {
 		wms_cmd = &sme_cmd->u.wmStatusChangeCmd;
-		if (wms_cmd->Type == eCsrDisassociated)
+		if (wms_cmd->Type == eCsrDisassociated) {
 			qdf_copy_macaddr(
 				&peer_macaddr,
 				&wms_cmd->u.DisassocIndMsg.peer_macaddr);
-		else if (wms_cmd->Type == eCsrDeauthenticated)
+			if (!qdf_is_macaddr_zero(
+				&wms_cmd->u.DisassocIndMsg.peer_mld_addr))
+				qdf_copy_macaddr(
+					&peer_mld_addr,
+					&wms_cmd->u.DisassocIndMsg.peer_mld_addr);
+		} else if (wms_cmd->Type == eCsrDeauthenticated) {
 			qdf_copy_macaddr(
 				&peer_macaddr,
 				&wms_cmd->u.DeauthIndMsg.peer_macaddr);
+			if (!qdf_is_macaddr_zero(
+				&wms_cmd->u.DeauthIndMsg.peer_mld_addr))
+				qdf_copy_macaddr(
+					&peer_mld_addr,
+					&wms_cmd->u.DeauthIndMsg.peer_mld_addr);
+		}
 	}
 
+	if (!qdf_is_macaddr_zero(&peer_mld_addr))
+		qdf_scnprintf(mld_log_str, MAC_ADDR_DUMP_LEN,
+			      " mld: " QDF_MAC_ADDR_FMT,
+			      QDF_MAC_ADDR_REF(peer_mld_addr.bytes));
+
 	if (!qdf_is_macaddr_zero(&peer_macaddr))
-		sme_err("vdev %d cmd %d timeout for peer " QDF_MAC_ADDR_FMT,
+		sme_err("vdev %d cmd %d timeout for peer " QDF_MAC_ADDR_FMT "%s",
 			sme_cmd->vdev_id, sme_cmd->command,
-			QDF_MAC_ADDR_REF(peer_macaddr.bytes));
+			QDF_MAC_ADDR_REF(peer_macaddr.bytes), mld_log_str);
+
 }
 
 QDF_STATUS sme_ser_cmd_callback(struct wlan_serialization_command *cmd,

+ 182 - 136
core/sme/src/csr/csr_api_roam.c

@@ -2311,14 +2311,19 @@ QDF_STATUS csr_roam_call_callback(struct mac_context *mac, uint32_t sessionId,
 }
 
 static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd,
-				   struct qdf_mac_addr peer_macaddr,
+				   struct qdf_mac_addr *peer_macaddr,
+				   struct qdf_mac_addr *peer_mld_addr,
 				   uint8_t vdev_id)
 {
 	if (sme_cmd->command == eSmeCommandRoam &&
 	    (sme_cmd->u.roamCmd.roamReason == eCsrForcedDisassocSta ||
 	     sme_cmd->u.roamCmd.roamReason == eCsrForcedDeauthSta) &&
-	    !qdf_mem_cmp(peer_macaddr.bytes, sme_cmd->u.roamCmd.peerMac,
-			 QDF_MAC_ADDR_SIZE))
+	     (qdf_is_macaddr_equal(
+			peer_macaddr,
+			(struct qdf_mac_addr *)sme_cmd->u.roamCmd.peerMac) ||
+	      (!qdf_is_macaddr_zero(peer_mld_addr) &&
+	       qdf_is_macaddr_equal(peer_mld_addr,
+				    &sme_cmd->u.roamCmd.peer_mld_addr))))
 		return true;
 
 	if (sme_cmd->command == eSmeCommandWmStatusChange) {
@@ -2326,15 +2331,23 @@ static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd,
 
 		wms_cmd = &sme_cmd->u.wmStatusChangeCmd;
 		if (wms_cmd->Type == eCsrDisassociated &&
-		    !qdf_mem_cmp(peer_macaddr.bytes,
-				 wms_cmd->u.DisassocIndMsg.peer_macaddr.bytes,
-				 QDF_MAC_ADDR_SIZE))
+		    (qdf_is_macaddr_equal(
+				peer_macaddr,
+				&wms_cmd->u.DisassocIndMsg.peer_macaddr) ||
+		     (!qdf_is_macaddr_zero(peer_mld_addr) &&
+		      qdf_is_macaddr_equal(
+				peer_mld_addr,
+				&wms_cmd->u.DisassocIndMsg.peer_mld_addr))))
 			return true;
 
 		if (wms_cmd->Type == eCsrDeauthenticated &&
-		    !qdf_mem_cmp(peer_macaddr.bytes,
-				 wms_cmd->u.DeauthIndMsg.peer_macaddr.bytes,
-				 QDF_MAC_ADDR_SIZE))
+		    (qdf_is_macaddr_equal(
+				peer_macaddr,
+				&wms_cmd->u.DeauthIndMsg.peer_macaddr) ||
+		     (!qdf_is_macaddr_zero(peer_mld_addr) &&
+		      qdf_is_macaddr_equal(
+				peer_mld_addr,
+				&wms_cmd->u.DeauthIndMsg.peer_mld_addr))))
 			return true;
 	}
 
@@ -2344,7 +2357,8 @@ static bool csr_peer_mac_match_cmd(tSmeCmd *sme_cmd,
 static bool
 csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx,
 				    uint8_t vdev_id,
-				    struct qdf_mac_addr peer_macaddr)
+				    struct qdf_mac_addr *peer_macaddr,
+				    struct qdf_mac_addr *peer_mld_addr)
 {
 	tListElem *entry = NULL;
 	tSmeCmd *sme_cmd;
@@ -2353,7 +2367,8 @@ csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx,
 	while (entry) {
 		sme_cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
 		if ((sme_cmd->vdev_id == vdev_id) &&
-		    csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
+		    csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
+					   peer_mld_addr, vdev_id))
 			return true;
 		entry = csr_nonscan_pending_ll_next(mac_ctx, entry,
 						    LL_ACCESS_NOLOCK);
@@ -2365,20 +2380,23 @@ csr_is_deauth_disassoc_in_pending_q(struct mac_context *mac_ctx,
 static bool
 csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
 				   uint8_t vdev_id,
-				   struct qdf_mac_addr peer_macaddr)
+				   struct qdf_mac_addr *peer_macaddr,
+				   struct qdf_mac_addr *peer_mld_addr)
 {
 	tSmeCmd *sme_cmd;
 
 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
 						WLAN_SER_CMD_FORCE_DEAUTH_STA);
 
-	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
+	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
+					      peer_mld_addr, vdev_id))
 		return true;
 
 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
 					WLAN_SER_CMD_FORCE_DISASSOC_STA);
 
-	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
+	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
+					      peer_mld_addr, vdev_id))
 		return true;
 
 	/*
@@ -2387,7 +2405,8 @@ csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
 	 */
 	sme_cmd = wlan_serialization_get_active_cmd(mac_ctx->psoc, vdev_id,
 						WLAN_SER_CMD_WM_STATUS_CHANGE);
-	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr, vdev_id))
+	if (sme_cmd && csr_peer_mac_match_cmd(sme_cmd, peer_macaddr,
+					      peer_mld_addr, vdev_id))
 		return true;
 
 	return false;
@@ -2398,7 +2417,8 @@ csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
  *  disassoc is already in progress.
  * @mac_ctx: Global MAC context
  * @vdev_id: vdev id
- * @peer_macaddr: Peer MAC address
+ * @peer_macaddr: Peer MAC address to check
+ * @peer_mld_addr: peer MLD address to check
  *
  * Return: True if deauth/disassoc indication can be dropped
  *  else false
@@ -2406,111 +2426,136 @@ csr_is_deauth_disassoc_in_active_q(struct mac_context *mac_ctx,
 static bool
 csr_is_deauth_disassoc_already_active(struct mac_context *mac_ctx,
 				      uint8_t vdev_id,
-				      struct qdf_mac_addr peer_macaddr)
+				      struct qdf_mac_addr *peer_macaddr,
+				      struct qdf_mac_addr *peer_mld_addr)
 {
-	bool ret = csr_is_deauth_disassoc_in_pending_q(mac_ctx,
-						      vdev_id,
-						      peer_macaddr);
+	char mld_log_str[MAC_ADDR_DUMP_LEN] = {0};
+
+	bool ret = csr_is_deauth_disassoc_in_pending_q(
+					mac_ctx, vdev_id, peer_macaddr,
+					peer_mld_addr);
 	if (!ret)
 		/**
 		 * commands are not found in pending queue, check in active
 		 * queue as well
 		 */
-		ret = csr_is_deauth_disassoc_in_active_q(mac_ctx,
-							  vdev_id,
-							  peer_macaddr);
+		ret = csr_is_deauth_disassoc_in_active_q(
+					mac_ctx, vdev_id,
+					peer_macaddr, peer_mld_addr);
 
-	if (ret)
-		sme_debug("Deauth/Disassoc already in progress for "QDF_MAC_ADDR_FMT,
-			  QDF_MAC_ADDR_REF(peer_macaddr.bytes));
+	if (ret) {
+		if (!qdf_is_macaddr_zero((struct qdf_mac_addr *)&peer_mld_addr))
+			qdf_scnprintf(mld_log_str, MAC_ADDR_DUMP_LEN,
+				      " mld: " QDF_MAC_ADDR_FMT,
+				      QDF_MAC_ADDR_REF(peer_mld_addr->bytes));
+		sme_debug("Deauth/Disassoc already in progress for " QDF_MAC_ADDR_FMT "%s",
+			  QDF_MAC_ADDR_REF(peer_macaddr->bytes), mld_log_str);
+	}
 
 	return ret;
 }
 
-/**
- * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station
- * @sessionId:     Session Id for Soft AP
- * @p_del_sta_params: Pointer to parameters of the station to disassoc
- *
- * CSR function that HDD calls to delete a associated station
+/*
+ * csr_is_deauth_disassoc_cmd_active() - Function to check if deauth or
+ *  disassoc is already in progress.
+ * @mac_ctx: Global MAC context
+ * @vdev_id: vdev ID
+ * @macaddr: mac address provided (mld/link/mac for the peer to check)
+ * @peer_mac: found peer mac
+ * @peer_mld_mac: found peer mld if ML connection
  *
- * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error
+ * Return: True if deauth/disassoc indication can be dropped else false
  */
-QDF_STATUS csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
-					       uint32_t sessionId,
-					       struct csr_del_sta_params
-					       *p_del_sta_params)
+static bool
+csr_is_deauth_disassoc_cmd_active(struct mac_context *mac_ctx,
+				  uint8_t vdev_id, struct qdf_mac_addr macaddr,
+				  struct qdf_mac_addr *peer_mac,
+				  struct qdf_mac_addr *peer_mld_mac)
+{
+	struct peer_mac_addresses peer_mac_info;
+
+	qdf_mem_zero(&peer_mac_info, sizeof(struct peer_mac_addresses));
+	qdf_copy_macaddr(&peer_mac_info.mac, &macaddr);
+	wlan_find_peer_and_get_mac_and_mld_addr(mac_ctx->psoc, &peer_mac_info);
+	if (csr_is_deauth_disassoc_already_active(mac_ctx, vdev_id,
+						  &peer_mac_info.peer_mac,
+						  &peer_mac_info.peer_mld))
+		return true;
 
+	if (peer_mac && peer_mld_mac) {
+		if (!qdf_is_macaddr_equal(&macaddr, &peer_mac_info.peer_mac))
+			sme_debug("Vdev %d, given mac " QDF_MAC_ADDR_FMT " found peer mac " QDF_MAC_ADDR_FMT,
+				  vdev_id, QDF_MAC_ADDR_REF(macaddr.bytes),
+				  QDF_MAC_ADDR_REF(peer_mac_info.peer_mac.bytes));
+		qdf_copy_macaddr(peer_mac, &peer_mac_info.peer_mac);
+		qdf_copy_macaddr(peer_mld_mac, &peer_mac_info.peer_mld);
+	}
+
+	return false;
+}
+
+static QDF_STATUS
+csr_roam_issue_discon_sta_roam_cmd(struct mac_context *mac,
+				   uint8_t vdev_id,
+				   enum csr_roam_reason discon_reason,
+				   struct csr_del_sta_params *del_sta_params)
 {
+	tSmeCmd *cmd;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	tSmeCmd *pCommand;
+	struct qdf_mac_addr peer_mac = QDF_MAC_ADDR_ZERO_INIT;
+	struct qdf_mac_addr peer_mld_mac = QDF_MAC_ADDR_ZERO_INIT;
 
-	do {
-		if (csr_is_deauth_disassoc_already_active(mac, sessionId,
-					      p_del_sta_params->peerMacAddr))
-			break;
-		pCommand = csr_get_command_buffer(mac);
-		if (!pCommand) {
-			sme_err("fail to get command buffer");
-			status = QDF_STATUS_E_RESOURCES;
-			break;
-		}
-		pCommand->command = eSmeCommandRoam;
-		pCommand->vdev_id = (uint8_t) sessionId;
-		pCommand->u.roamCmd.roamReason = eCsrForcedDisassocSta;
-		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
-				p_del_sta_params->peerMacAddr.bytes,
-				sizeof(pCommand->u.roamCmd.peerMac));
-		pCommand->u.roamCmd.reason = p_del_sta_params->reason_code;
+	if (csr_is_deauth_disassoc_cmd_active(mac, vdev_id,
+					      del_sta_params->peerMacAddr,
+					      &peer_mac, &peer_mld_mac))
+		return status;
 
-		status = csr_queue_sme_command(mac, pCommand, false);
-		if (!QDF_IS_STATUS_SUCCESS(status))
-			sme_err("fail to send message status: %d", status);
-	} while (0);
+	cmd = csr_get_command_buffer(mac);
+	if (!cmd) {
+		sme_err("Vdev %d " QDF_MAC_ADDR_FMT " fails to get command buffer for reason %d",
+			vdev_id,
+			QDF_MAC_ADDR_REF(del_sta_params->peerMacAddr.bytes),
+			discon_reason);
+		return QDF_STATUS_E_RESOURCES;
+	}
+
+	cmd->command = eSmeCommandRoam;
+	cmd->vdev_id = vdev_id;
+	cmd->u.roamCmd.roamReason = discon_reason;
+	qdf_copy_macaddr((struct qdf_mac_addr *)&cmd->u.roamCmd.peerMac,
+			 &peer_mac);
+	qdf_copy_macaddr(&cmd->u.roamCmd.peer_mld_addr, &peer_mld_mac);
+	cmd->u.roamCmd.reason = del_sta_params->reason_code;
+
+	status = csr_queue_sme_command(mac, cmd, false);
+	if (QDF_IS_STATUS_ERROR(status))
+		sme_err("Vdev %d " QDF_MAC_ADDR_FMT " fails to get send message status: %d",
+			vdev_id,
+			QDF_MAC_ADDR_REF(del_sta_params->peerMacAddr.bytes),
+			status);
 
 	return status;
 }
 
-/**
- * csr_roam_issue_deauthSta() - delete a associated station
- * @sessionId:     Session Id for Soft AP
- * @pDelStaParams: Pointer to parameters of the station to deauthenticate
- *
- * CSR function that HDD calls to delete a associated station
- *
- * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error
- */
-QDF_STATUS csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
-		uint32_t sessionId,
-		struct csr_del_sta_params *pDelStaParams)
-{
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	tSmeCmd *pCommand;
-
-	do {
-		if (csr_is_deauth_disassoc_already_active(mac, sessionId,
-					      pDelStaParams->peerMacAddr))
-			break;
-		pCommand = csr_get_command_buffer(mac);
-		if (!pCommand) {
-			sme_err("fail to get command buffer");
-			status = QDF_STATUS_E_RESOURCES;
-			break;
-		}
-		pCommand->command = eSmeCommandRoam;
-		pCommand->vdev_id = (uint8_t) sessionId;
-		pCommand->u.roamCmd.roamReason = eCsrForcedDeauthSta;
-		qdf_mem_copy(pCommand->u.roamCmd.peerMac,
-			     pDelStaParams->peerMacAddr.bytes,
-			     sizeof(tSirMacAddr));
-		pCommand->u.roamCmd.reason = pDelStaParams->reason_code;
+QDF_STATUS
+csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
+				    uint8_t vdev_id,
+				    struct csr_del_sta_params *del_sta_params)
 
-		status = csr_queue_sme_command(mac, pCommand, false);
-		if (!QDF_IS_STATUS_SUCCESS(status))
-			sme_err("fail to send message status: %d", status);
-	} while (0);
+{
+	return csr_roam_issue_discon_sta_roam_cmd(mac, vdev_id,
+						  eCsrForcedDisassocSta,
+						  del_sta_params);
+}
 
-	return status;
+QDF_STATUS
+csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
+			      uint8_t vdev_id,
+			      struct csr_del_sta_params *del_sta_params)
+{
+	return csr_roam_issue_discon_sta_roam_cmd(mac, vdev_id,
+						  eCsrForcedDeauthSta,
+						  del_sta_params);
 }
 
 /**
@@ -4081,50 +4126,47 @@ static void
 csr_roam_chk_lnk_disassoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {
 	struct csr_roam_session *session;
-	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
-	struct disassoc_ind *pDisassocInd;
+	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	struct disassoc_ind *disassoc_ind;
 
 	/*
 	 * Check if AP dis-associated us because of MIC failure. If so,
 	 * then we need to take action immediately and not wait till the
 	 * the WmStatusChange requests is pushed and processed
 	 */
-	pDisassocInd = (struct disassoc_ind *)msg_ptr;
-	sessionId = pDisassocInd->vdev_id;
-	sme_debug("Disassoc Indication from MAC for vdev_id %d bssid " QDF_MAC_ADDR_FMT,
-		  pDisassocInd->vdev_id,
-		  QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
+	disassoc_ind = (struct disassoc_ind *)msg_ptr;
+	vdev_id = disassoc_ind->vdev_id;
 
-	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
+	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
 		sme_err("vdev:%d Invalid session. BSSID: " QDF_MAC_ADDR_FMT,
-			sessionId, QDF_MAC_ADDR_REF(pDisassocInd->bssid.bytes));
+			vdev_id, QDF_MAC_ADDR_REF(disassoc_ind->bssid.bytes));
 
 		return;
 	}
 
-	if (!csr_if_peer_present(mac_ctx, &pDisassocInd->bssid.bytes[0],
-				 &pDisassocInd->peer_macaddr.bytes[0]))
+	if (!csr_if_peer_present(mac_ctx, &disassoc_ind->bssid.bytes[0],
+				 &disassoc_ind->peer_macaddr.bytes[0]))
 		return;
 
-	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
-	    pDisassocInd->peer_macaddr))
+	if (csr_is_deauth_disassoc_cmd_active(mac_ctx, vdev_id,
+					      disassoc_ind->peer_macaddr,
+					      &disassoc_ind->peer_macaddr,
+					      &disassoc_ind->peer_mld_addr))
 		return;
 
-	sme_nofl_info("disassoc from peer " QDF_MAC_ADDR_FMT
-		      "reason: %d status: %d vid %d",
-		      QDF_MAC_ADDR_REF(pDisassocInd->peer_macaddr.bytes),
-		      pDisassocInd->reasonCode,
-		      pDisassocInd->status_code, sessionId);
-	session = CSR_GET_SESSION(mac_ctx, sessionId);
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
 	if (!session) {
-		sme_err("session: %d not found", sessionId);
+		sme_err("vdev %d session not found", vdev_id);
 		return;
 	}
+	sme_debug("Vdev %d, peer " QDF_MAC_ADDR_FMT " reason: %d status: %d",
+		  vdev_id, QDF_MAC_ADDR_REF(disassoc_ind->peer_macaddr.bytes),
+		  disassoc_ind->reasonCode, disassoc_ind->status_code);
 	/* Update the disconnect stats */
 	session->disconnect_stats.disconnection_cnt++;
 	session->disconnect_stats.disassoc_by_peer++;
 
-	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+	csr_roam_issue_wm_status_change(mac_ctx, vdev_id,
 					eCsrDisassociated, msg_ptr);
 }
 
@@ -4132,36 +4174,40 @@ static void
 csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 {
 	struct csr_roam_session *session;
-	uint32_t sessionId = WLAN_UMAC_VDEV_ID_MAX;
-	struct deauth_ind *pDeauthInd;
+	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+	struct deauth_ind *deauth_ind;
 
-	pDeauthInd = (struct deauth_ind *)msg_ptr;
-	sme_debug("DEAUTH Indication from MAC for vdev_id %d bssid "QDF_MAC_ADDR_FMT,
-		  pDeauthInd->vdev_id,
-		  QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes));
+	deauth_ind = (struct deauth_ind *)msg_ptr;
 
-	sessionId = pDeauthInd->vdev_id;
-	if (!CSR_IS_SESSION_VALID(mac_ctx, sessionId)) {
+	vdev_id = deauth_ind->vdev_id;
+	if (!CSR_IS_SESSION_VALID(mac_ctx, vdev_id)) {
 		sme_err("vdev %d: Invalid session BSSID: " QDF_MAC_ADDR_FMT,
-			pDeauthInd->vdev_id,
-			QDF_MAC_ADDR_REF(pDeauthInd->bssid.bytes));
+			deauth_ind->vdev_id,
+			QDF_MAC_ADDR_REF(deauth_ind->bssid.bytes));
 		return;
 	}
 
-	if (!csr_if_peer_present(mac_ctx, &pDeauthInd->bssid.bytes[0],
-				 &pDeauthInd->peer_macaddr.bytes[0]))
+	if (!csr_if_peer_present(mac_ctx, &deauth_ind->bssid.bytes[0],
+				 &deauth_ind->peer_macaddr.bytes[0]))
 		return;
 
-	if (csr_is_deauth_disassoc_already_active(mac_ctx, sessionId,
-	    pDeauthInd->peer_macaddr))
+	if (csr_is_deauth_disassoc_cmd_active(mac_ctx, vdev_id,
+					      deauth_ind->peer_macaddr,
+					      &deauth_ind->peer_macaddr,
+					      &deauth_ind->peer_mld_addr))
 		return;
-	session = CSR_GET_SESSION(mac_ctx, sessionId);
+
+	session = CSR_GET_SESSION(mac_ctx, vdev_id);
 	if (!session) {
-		sme_err("session %d not found", sessionId);
+		sme_err("vdev %d session not found", vdev_id);
 		return;
 	}
+	sme_debug("vdev %d bssid " QDF_MAC_ADDR_FMT " reason: %d status: %d",
+		  deauth_ind->vdev_id,
+		  QDF_MAC_ADDR_REF(deauth_ind->bssid.bytes),
+		  deauth_ind->reasonCode, deauth_ind->status_code);
 	/* Update the disconnect stats */
-	switch (pDeauthInd->reasonCode) {
+	switch (deauth_ind->reasonCode) {
 	case REASON_DISASSOC_DUE_TO_INACTIVITY:
 		session->disconnect_stats.disconnection_cnt++;
 		session->disconnect_stats.peer_kickout++;
@@ -4184,7 +4230,7 @@ csr_roam_chk_lnk_deauth_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
 		break;
 	}
 
-	csr_roam_issue_wm_status_change(mac_ctx, sessionId,
+	csr_roam_issue_wm_status_change(mac_ctx, vdev_id,
 					eCsrDeauthenticated,
 					msg_ptr);
 }

+ 15 - 14
core/sme/src/csr/csr_inside_api.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -374,31 +374,32 @@ QDF_STATUS csr_roam_issue_stop_bss_cmd(struct mac_context *mac, uint8_t vdev_id,
 
 /**
  * csr_roam_issue_disassociate_sta_cmd() - disassociate a associated station
- * @mac:          Pointer to global structure for MAC
- * @sessionId:     Session Id for Soft AP
- * @p_del_sta_params: Pointer to parameters of the station to disassoc
+ * @mac: Pointer to global structure for MAC
+ * @vdev_id: vdev Id for Soft AP
+ * @del_sta_params: Pointer to parameters of the station to disassoc
  *
  * CSR function that HDD calls to issue a deauthenticate station command
  *
  * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_* on error
  */
-QDF_STATUS csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
-					       uint32_t sessionId,
-					       struct csr_del_sta_params
-					       *p_del_sta_params);
+QDF_STATUS
+csr_roam_issue_disassociate_sta_cmd(struct mac_context *mac,
+				    uint8_t vdev_id,
+				    struct csr_del_sta_params *del_sta_params);
 /**
  * csr_roam_issue_deauth_sta_cmd() - issue deauthenticate station command
- * @mac:          Pointer to global structure for MAC
- * @sessionId:     Session Id for Soft AP
- * @pDelStaParams: Pointer to parameters of the station to deauthenticate
+ * @mac: Pointer to global structure for MAC
+ * @vdev_id: vdev Id for Soft AP
+ * @del_sta_params: Pointer to parameters of the station to deauthenticate
  *
  * CSR function that HDD calls to issue a deauthenticate station command
  *
  * Return: QDF_STATUS_SUCCESS on success or another QDF_STATUS_** on error
  */
-QDF_STATUS csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
-		uint32_t sessionId,
-		struct csr_del_sta_params *pDelStaParams);
+QDF_STATUS
+csr_roam_issue_deauth_sta_cmd(struct mac_context *mac,
+			      uint8_t vdev_id,
+			      struct csr_del_sta_params *del_sta_params);
 
 /*
  * csr_send_chng_mcc_beacon_interval() -