Browse Source

qcacld-3.0: Send deauth frame to STA if OCI is invalid

After channel switches to new channel, STA sends sa query request to
AP/SAP device. SAP process sa query request and if OCI is invalid in
that sa query, then it sends deauth to STA on new channel.

Change-Id: I52a5dcaf2e0826d3bd899d7f52f02400927c4ae6
CRs-Fixed: 3227530
Rahul Gusain 2 years ago
parent
commit
6dc9fa750c

+ 2 - 0
core/mac/src/dph/dph_hash_table.c

@@ -334,6 +334,8 @@ QDF_STATUS dph_delete_hash_entry(struct mac_context *mac, tSirMacAddr staAddr,
 		ptr->added = 0;
 		ptr->is_disassoc_deauth_in_progress = 0;
 		ptr->sta_deletion_in_progress = false;
+		ptr->ocv_enabled = 0;
+		ptr->last_ocv_done_freq = 0;
 		ptr->next = 0;
 	} else {
 		pe_err("Entry not present STA addr: "QDF_MAC_ADDR_FMT,

+ 2 - 0
core/mac/src/include/dph_global.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -183,6 +184,7 @@ typedef struct sDphHashNode {
 	/* Flag indicating connected STA doesn't support ECSA */
 	uint8_t non_ecsa_capable;
 	struct parsed_ies parsed_ies;
+	uint32_t last_ocv_done_freq;
 
 #ifdef WLAN_FEATURE_11AX
 	tDot11fIEhe_cap he_config;

+ 13 - 3
core/mac/src/pe/lim/lim_link_monitoring_algo.c

@@ -93,9 +93,19 @@ static void lim_delete_sta_util(struct mac_context *mac_ctx, tpDeleteStaContext
 			pe_err("Inv Del STA assocId: %d", msg->assocId);
 			return;
 		} else {
-			lim_send_disassoc_mgmt_frame(mac_ctx,
-				REASON_DISASSOC_DUE_TO_INACTIVITY,
-				stads->staAddr, session_entry, false);
+			if (stads->ocv_enabled && stads->last_ocv_done_freq !=
+			    session_entry->curr_op_freq) {
+				lim_send_deauth_mgmt_frame(
+						mac_ctx,
+						REASON_PREV_AUTH_NOT_VALID,
+						stads->staAddr,
+						session_entry, false);
+			} else {
+				lim_send_disassoc_mgmt_frame(
+					mac_ctx,
+					REASON_DISASSOC_DUE_TO_INACTIVITY,
+					stads->staAddr, session_entry, false);
+			}
 			lim_trigger_sta_deletion(mac_ctx, stads, session_entry);
 		}
 	} else {

+ 25 - 1
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -1278,6 +1278,8 @@ static void __lim_process_sa_query_request_action_frame(struct mac_context *mac,
 	uint8_t *p_body;
 	uint32_t frame_len;
 	uint8_t transId[2];
+	tpDphHashNode sta_ds;
+	uint16_t aid;
 
 	/* Prima  --- Below Macro not available in prima
 	   pHdr = SIR_MAC_BD_TO_MPDUHEADER(pBd);
@@ -1309,11 +1311,33 @@ static void __lim_process_sa_query_request_action_frame(struct mac_context *mac,
 	   Transaction ID : 2 bytes */
 	qdf_mem_copy(&transId[0], &p_body[2], 2);
 
+	sta_ds = dph_lookup_hash_entry(mac, mac_header->sa, &aid,
+				       &pe_session->dph.dphHashTable);
+
 	if (!lim_check_oci_match(mac, pe_session,
 				 p_body + SA_QUERY_IE_OFFSET,
 				 mac_header->sa,
-				 frame_len - SA_QUERY_IE_OFFSET))
+				 frame_len - SA_QUERY_IE_OFFSET)) {
+		/*
+		 * In case of channel switch, last ocv frequency will be
+		 * different from current frquency.
+		 * If there is channel switch and OCI is inavlid in sa_query,
+		 * deauth STA on new channel.
+		 */
+		if (sta_ds && sta_ds->ocv_enabled &&
+		    sta_ds->last_ocv_done_freq != pe_session->curr_op_freq)
+			lim_send_deauth_mgmt_frame(mac, REASON_OCI_MISMATCH,
+						   mac_header->sa, pe_session,
+						   false);
 		return;
+	}
+
+	/*
+	 * Update the last ocv done freq when OCI is valid.
+	 * To support above algo, if it is moved to the current freq.
+	 */
+	if (sta_ds && sta_ds->ocv_enabled)
+		sta_ds->last_ocv_done_freq = pe_session->curr_op_freq;
 
 	/* Send 11w SA query response action frame */
 	if (lim_send_sa_query_response_frame(mac,

+ 2 - 0
core/mac/src/pe/lim/lim_process_assoc_req_frame.c

@@ -1895,6 +1895,8 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tSirMacAddr sa,
 	if (sta_ds->rmfEnabled) {
 		sta_ds->ocv_enabled = lim_is_ocv_enable_in_assoc_req(mac_ctx,
 								     assoc_req);
+		if (sta_ds->ocv_enabled)
+			sta_ds->last_ocv_done_freq = session->curr_op_freq;
 		/* Try to delete it before, creating.*/
 		lim_delete_pmf_query_timer(sta_ds);
 		if (tx_timer_create(mac_ctx, &sta_ds->pmfSaQueryTimer,