blob: f1a8697034beba3570d6fc6b2934d0fdc186f98d [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Ashish Kumar Dhanotiya46f2ca02017-02-25 00:45:29 +05302 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*
29 *
30 * This file lim_process_disassoc_frame.cc contains the code
31 * for processing Disassocation Frame.
32 * Author: Chandra Modumudi
33 * Date: 03/24/02
34 * History:-
35 * Date Modified by Modification Information
36 * --------------------------------------------------------------------
37 *
38 */
39#include "cds_api.h"
40#include "wni_api.h"
41#include "sir_api.h"
42#include "ani_global.h"
43#include "wni_cfg.h"
44
45#include "utils_api.h"
46#include "lim_types.h"
47#include "lim_utils.h"
48#include "lim_assoc_utils.h"
49#include "lim_security_utils.h"
50#include "lim_ser_des_utils.h"
51#include "lim_send_messages.h"
52#include "sch_api.h"
53
54/**
55 * lim_process_disassoc_frame
56 *
57 ***FUNCTION:
58 * This function is called by limProcessMessageQueue() upon
59 * Disassociation frame reception.
60 *
61 ***LOGIC:
62 *
63 ***ASSUMPTIONS:
64 * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
65 *
66 ***NOTE:
67 *
68 * @param pMac - Pointer to Global MAC structure
69 * @param *pRxPacketInfo - A pointer to Rx packet info structure
70 * @return None
71 */
72void
73lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
74 tpPESession psessionEntry)
75{
76 uint8_t *pBody;
77 uint16_t aid, reasonCode;
78 tpSirMacMgmtHdr pHdr;
79 tpDphHashNode pStaDs;
80 tLimMlmDisassocInd mlmDisassocInd;
81#ifdef WLAN_FEATURE_11W
82 uint32_t frameLen;
83#endif
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053084 int32_t frame_rssi;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085
86 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
87 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
88
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053089 frame_rssi = (int32_t)WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
90
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091 if (lim_is_group_addr(pHdr->sa)) {
92 /* Received Disassoc frame from a BC/MC address */
93 /* Log error and ignore it */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +053094 pe_err("received Disassoc frame from a BC/MC address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095 return;
96 }
97
98 if (lim_is_group_addr(pHdr->da) && !lim_is_addr_bc(pHdr->da)) {
99 /* Received Disassoc frame for a MC address */
100 /* Log error and ignore it */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530101 pe_err("received Disassoc frame for a MC address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102 return;
103 }
104 if (!lim_validate_received_frame_a1_addr(pMac,
105 pHdr->da, psessionEntry)) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530106 pe_err("rx frame doesn't have valid a1 address, drop it");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107 return;
108 }
109
110 if (LIM_IS_STA_ROLE(psessionEntry) &&
Sandeep Puligillaf4810702017-04-19 17:07:03 -0700111 ((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) ||
112 (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) {
113 if (!(pMac->lim.disassocMsgCnt & 0xF)) {
114 pe_info("received Disassoc frame in %s"
115 "(already processing previously received Disassoc frame)"
116 "Dropping this.. Disassoc Failed %d",
117 lim_sme_state_str(psessionEntry->limSmeState),
118 ++pMac->lim.disassocMsgCnt);
119 } else {
120 pMac->lim.disassocMsgCnt++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800121 }
Sandeep Puligillaf4810702017-04-19 17:07:03 -0700122 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123 }
124#ifdef WLAN_FEATURE_11W
125 /* PMF: If this session is a PMF session, then ensure that this frame was protected */
126 if (psessionEntry->limRmfEnabled
127 && (WMA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) &
128 DPU_FEEDBACK_UNPROTECTED_ERROR)) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530129 pe_err("received an unprotected disassoc from AP");
mukul sharma72c8b222015-09-04 17:02:01 +0530130 /*
131 * When 11w offload is enabled then
132 * firmware should not fwd this frame
133 */
134 if (LIM_IS_STA_ROLE(psessionEntry) && pMac->pmf_offload) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530135 pe_err("11w offload is enable,unprotected disassoc is not expected");
mukul sharma72c8b222015-09-04 17:02:01 +0530136 return;
137 }
138
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800139 /* If the frame received is unprotected, forward it to the supplicant to initiate */
140 /* an SA query */
141 frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
142 /* send the unprotected frame indication to SME */
143 lim_send_sme_unprotected_mgmt_frame_ind(pMac, pHdr->fc.subType,
144 (uint8_t *) pHdr,
145 (frameLen +
146 sizeof(tSirMacMgmtHdr)),
147 psessionEntry->smeSessionId,
148 psessionEntry);
149 return;
150 }
151#endif
152
153 /* Get reasonCode from Disassociation frame body */
154 reasonCode = sir_read_u16(pBody);
155
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530156 pe_err("Received Disassoc frame for Addr: " MAC_ADDRESS_STR
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530157 "(mlm state=%s, sme state=%d RSSI=%d),"
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530158 "with reason code %d [%s] from " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800159 MAC_ADDR_ARRAY(pHdr->da),
160 lim_mlm_state_str(psessionEntry->limMlmState),
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530161 psessionEntry->limSmeState, frame_rssi, reasonCode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162 lim_dot11_reason_str(reasonCode), MAC_ADDR_ARRAY(pHdr->sa));
Sen, Devendra154b3c42017-02-13 20:44:15 +0530163 lim_diag_event_report(pMac, WLAN_PE_DIAG_DISASSOC_FRAME_EVENT,
164 psessionEntry, 0, reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800165 /**
166 * Extract 'associated' context for STA, if any.
167 * This is maintained by DPH and created by LIM.
168 */
169 pStaDs =
170 dph_lookup_hash_entry(pMac, pHdr->sa, &aid,
171 &psessionEntry->dph.dphHashTable);
172
173 if (pStaDs == NULL) {
174 /**
175 * Disassociating STA is not associated.
176 * Log error.
177 */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530178 pe_err("received Disassoc frame from STA that does not have context"
179 "reasonCode=%d, addr " MAC_ADDRESS_STR,
Nishank Aggarwal514f2632017-04-20 11:27:24 +0530180 reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800181 return;
182 }
183
184 if (lim_check_disassoc_deauth_ack_pending(pMac, (uint8_t *) pHdr->sa)) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530185 pe_err("Ignore the DisAssoc received, while waiting for ack of disassoc/deauth");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800186 lim_clean_up_disassoc_deauth_req(pMac, (uint8_t *) pHdr->sa, 1);
187 return;
188 }
189
Sandeep Puligillaf4810702017-04-19 17:07:03 -0700190 if (pMac->lim.disassocMsgCnt != 0) {
191 pMac->lim.disassocMsgCnt = 0;
192 }
193
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800194 /** If we are in the Wait for ReAssoc Rsp state */
195 if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
196 /** If we had received the DisAssoc from,
197 * a. the Current AP during ReAssociate to different AP in same ESS
198 * b. Unknown AP
199 * drop/ignore the DisAssoc received
200 */
201 if (!IS_REASSOC_BSSID(pMac, pHdr->sa, psessionEntry)) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530202 pe_err("Ignore the DisAssoc received, while Processing ReAssoc with different/unknown AP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800203 return;
204 }
205 /** If the Disassoc is received from the new AP to which we tried to ReAssociate
206 * Drop ReAssoc and Restore the Previous context( current connected AP).
207 */
208 if (!IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530209 pe_debug("received Disassoc from the New AP to which ReAssoc is sent");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210 lim_restore_pre_reassoc_state(pMac,
211 eSIR_SME_REASSOC_REFUSED,
212 reasonCode,
213 psessionEntry);
214 return;
215 }
216 }
217
Rajeev Kumarcf835a02016-04-15 15:01:31 -0700218 if (LIM_IS_AP_ROLE(psessionEntry)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219 switch (reasonCode) {
220 case eSIR_MAC_UNSPEC_FAILURE_REASON:
221 case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
222 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
223 case eSIR_MAC_MIC_FAILURE_REASON:
224 case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
225 case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
226 case eSIR_MAC_RSN_IE_MISMATCH_REASON:
227 case eSIR_MAC_1X_AUTH_FAILURE_REASON:
228 /* Valid reasonCode in received Disassociation frame */
229 break;
230
231 default:
232 /* Invalid reasonCode in received Disassociation frame */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530233 pe_warn("received Disassoc frame with invalid reasonCode: %d from " MAC_ADDRESS_STR,
234 reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235 break;
236 }
Rajeev Kumarcf835a02016-04-15 15:01:31 -0700237 } else if (LIM_IS_STA_ROLE(psessionEntry) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800238 ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
239 (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
240 (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
241 (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE))) {
242 switch (reasonCode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800243 case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
244 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
245 /* Valid reasonCode in received Disassociation frame */
246 /* as long as we're not about to channel switch */
247 if (psessionEntry->gLimChannelSwitch.state !=
248 eLIM_CHANNEL_SWITCH_IDLE) {
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530249 pe_err("Ignoring disassoc frame due to upcoming channel switch, from "MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800250 MAC_ADDR_ARRAY(pHdr->sa));
251 return;
252 }
253 break;
254
255 default:
Srinivas Girigowdafae50102016-08-17 19:05:01 -0700256 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257 }
258 } else {
259 /* Received Disassociation frame in either IBSS */
260 /* or un-known role. Log and ignore it */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530261 pe_err("received Disassoc frame with invalid reasonCode: %d in role:"
262 "%d in sme state: %d from " MAC_ADDRESS_STR, reasonCode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800263 GET_LIM_SYSTEM_ROLE(psessionEntry), psessionEntry->limSmeState,
264 MAC_ADDR_ARRAY(pHdr->sa));
265
266 return;
267 }
268
269 if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
270 (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) {
271 /**
272 * Already in the process of deleting context for the peer
273 * and received Disassociation frame. Log and Ignore.
274 */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530275 pe_err("received Disassoc frame in state: %d from"
276 MAC_ADDRESS_STR, pStaDs->mlmStaContext.mlmState,
Nishank Aggarwal514f2632017-04-20 11:27:24 +0530277 MAC_ADDR_ARRAY(pHdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800278 return;
279 }
Ashish Kumar Dhanotiya46f2ca02017-02-25 00:45:29 +0530280#ifdef FEATURE_WLAN_TDLS
281 /**
282 * Delete all the TDLS peers only if Disassoc is received
283 * from the AP
284 */
285 if ((LIM_IS_STA_ROLE(psessionEntry)) &&
286 ((pStaDs->mlmStaContext.mlmState ==
287 eLIM_MLM_LINK_ESTABLISHED_STATE) ||
288 (pStaDs->mlmStaContext.mlmState ==
289 eLIM_MLM_IDLE_STATE)) &&
290 (IS_CURRENT_BSSID(pMac, pHdr->sa, psessionEntry)))
291 lim_delete_tdls_peers(pMac, psessionEntry);
292#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800293
294 if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) {
295 /**
296 * Requesting STA is in some 'transient' state?
297 * Log error.
298 */
299 if (pStaDs->mlmStaContext.mlmState ==
300 eLIM_MLM_WT_ASSOC_CNF_STATE)
301 pStaDs->mlmStaContext.updateContext = 1;
302
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530303 pe_err("received Disassoc frame from peer that is in state: %X, addr "MAC_ADDRESS_STR,
304 pStaDs->mlmStaContext.mlmState,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800305 MAC_ADDR_ARRAY(pHdr->sa));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800306
307 } /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */
308
309 pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
310 pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
311
312 /* Issue Disassoc Indication to SME. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530313 qdf_mem_copy((uint8_t *) &mlmDisassocInd.peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800314 (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));
315 mlmDisassocInd.reasonCode =
316 (uint8_t) pStaDs->mlmStaContext.disassocReason;
317 mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
318
319 /* Update PE session Id */
320 mlmDisassocInd.sessionId = psessionEntry->peSessionId;
321
322 if (lim_is_reassoc_in_progress(pMac, psessionEntry)) {
323
324 /* If we're in the middle of ReAssoc and received disassoc from
325 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
326 * failure result code. By design, SME will then issue "Disassoc"
327 * and cleanup will happen at that time.
328 */
Nishank Aggarwalfb8ddce2017-03-23 14:34:34 +0530329 pe_debug("received Disassoc from AP while waiting for Reassoc Rsp");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330
331 if (psessionEntry->limAssocResponseData) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530332 qdf_mem_free(psessionEntry->limAssocResponseData);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 psessionEntry->limAssocResponseData = NULL;
334 }
335
336 lim_restore_pre_reassoc_state(pMac, eSIR_SME_REASSOC_REFUSED,
337 reasonCode, psessionEntry);
338 return;
339 }
340
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +0530341 lim_update_lost_link_info(pMac, psessionEntry, frame_rssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800342 lim_post_sme_message(pMac, LIM_MLM_DISASSOC_IND,
343 (uint32_t *) &mlmDisassocInd);
344
345 /* send eWNI_SME_DISASSOC_IND to SME */
346 lim_send_sme_disassoc_ind(pMac, pStaDs, psessionEntry);
347
348 return;
349} /*** end lim_process_disassoc_frame() ***/