blob: 9e1591f20ff6c7bee759eea2230411e03a0a6b08 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
5 */
Gopichand Nakkala92f07d82013-01-08 21:16:34 -08006/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08007 * Airgo Networks, Inc proprietary. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07008 * This file limProcessDisassocFrame.cc contains the code
9 * for processing Disassocation Frame.
10 * Author: Chandra Modumudi
11 * Date: 03/24/02
12 * History:-
13 * Date Modified by Modification Information
14 * --------------------------------------------------------------------
15 *
16 */
17#include "palTypes.h"
18#include "wniApi.h"
19#include "sirApi.h"
20#include "aniGlobal.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070021#include "wniCfgSta.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070022
23#include "utilsApi.h"
24#include "limTypes.h"
25#include "limUtils.h"
26#include "limAssocUtils.h"
27#include "limSecurityUtils.h"
28#include "limSerDesUtils.h"
29#include "limSendMessages.h"
30#include "schApi.h"
31
32
33/**
34 * limProcessDisassocFrame
35 *
36 *FUNCTION:
37 * This function is called by limProcessMessageQueue() upon
38 * Disassociation frame reception.
39 *
40 *LOGIC:
41 *
42 *ASSUMPTIONS:
43 * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
44 *
45 *NOTE:
46 *
47 * @param pMac - Pointer to Global MAC structure
48 * @param *pRxPacketInfo - A pointer to Rx packet info structure
49 * @return None
50 */
51void
52limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
53{
54 tANI_U8 *pBody;
55 tANI_U16 aid, reasonCode;
56 tpSirMacMgmtHdr pHdr;
57 tpDphHashNode pStaDs;
58 tLimMlmDisassocInd mlmDisassocInd;
Chet Lanctot186b5732013-03-18 10:26:30 -070059#ifdef WLAN_FEATURE_11W
60 tANI_U32 frameLen;
61#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070062
63 pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
64 pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
65
66
67 if (limIsGroupAddr(pHdr->sa))
68 {
69 // Received Disassoc frame from a BC/MC address
70 // Log error and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +053071 PELOGE(limLog(pMac, LOGE,
Kiran Kumar Lokere531ca702013-04-01 13:24:23 -070072 FL("received Disassoc frame from a BC/MC address"));)
Jeff Johnson295189b2012-06-20 16:38:30 -070073
74 return;
75 }
76
77 if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da))
78 {
79 // Received Disassoc frame for a MC address
80 // Log error and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +053081 PELOGE(limLog(pMac, LOGE,
Kiran Kumar Lokere531ca702013-04-01 13:24:23 -070082 FL("received Disassoc frame for a MC address"));)
Jeff Johnson295189b2012-06-20 16:38:30 -070083
84 return;
85 }
86
Chet Lanctot186b5732013-03-18 10:26:30 -070087#ifdef WLAN_FEATURE_11W
88 /* PMF: If this session is a PMF session, then ensure that this frame was protected */
89 if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR))
90 {
91 PELOGE(limLog(pMac, LOGE, FL("received an unprotected disassoc from AP"));)
92 // If the frame received is unprotected, forward it to the supplicant to initiate
93 // an SA query
94 frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
95 //send the unprotected frame indication to SME
96 limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType,
97 (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)),
98 psessionEntry->smeSessionId, psessionEntry);
99 return;
100 }
101#endif
102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103 // Get reasonCode from Disassociation frame body
104 reasonCode = sirReadU16(pBody);
105
Kanchanapally, Vidyullathaf9426e52013-12-24 17:28:54 +0530106 PELOG2(limLog(pMac, LOGE,
107 FL("Received Disassoc frame for Addr: "MAC_ADDRESS_STR"(mlm state=%s, sme state=%d),"
108 "with reason code %d from "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da),
109 limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState, reasonCode,
110 MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112 /**
113 * Extract 'associated' context for STA, if any.
114 * This is maintained by DPH and created by LIM.
115 */
116 pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
117
118 if (pStaDs == NULL)
119 {
120 /**
121 * Disassociating STA is not associated.
122 * Log error.
123 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530124 PELOGE(limLog(pMac, LOGE,
125 FL("received Disassoc frame from STA that does not have context "
126 "reasonCode=%d, addr "MAC_ADDRESS_STR),
127 reasonCode,MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700128
129 return;
130 }
131
Madan Mohan Koyyalamudi25b6f8b2012-12-04 16:17:31 -0800132 if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa))
133 {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530134 PELOGE(limLog(pMac, LOGE,
135 FL("Ignore the DisAssoc received, while waiting "
136 "for ack of disassoc/deauth"));)
Madan Mohan Koyyalamudi25b6f8b2012-12-04 16:17:31 -0800137 limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1);
138 return;
139 }
140
Jeff Johnson295189b2012-06-20 16:38:30 -0700141 /** If we are in the Wait for ReAssoc Rsp state */
142 if (limIsReassocInProgress(pMac,psessionEntry)) {
143 /** If we had received the DisAssoc from,
144 * a. the Current AP during ReAssociate to different AP in same ESS
145 * b. Unknown AP
146 * drop/ignore the DisAssoc received
147 */
148 if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530149 PELOGE(limLog(pMac, LOGE, FL("Ignore the DisAssoc received, while "
150 "Processing ReAssoc with different/unknown AP"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700151 return;
152 }
153 /** If the Disassoc is received from the new AP to which we tried to ReAssociate
154 * Drop ReAssoc and Restore the Previous context( current connected AP).
155 */
156 if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530157 PELOGE(limLog(pMac, LOGE, FL("received Disassoc from the New AP to "
158 "which ReAssoc is sent "));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700159 limRestorePreReassocState(pMac,
160 eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
161 return;
162 }
163 }
164
165 if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
166 (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
167 {
168 switch (reasonCode)
169 {
170 case eSIR_MAC_UNSPEC_FAILURE_REASON:
171 case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
172 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
173 case eSIR_MAC_MIC_FAILURE_REASON:
174 case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
175 case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
176 case eSIR_MAC_RSN_IE_MISMATCH_REASON:
177 case eSIR_MAC_1X_AUTH_FAILURE_REASON:
178 // Valid reasonCode in received Disassociation frame
179 break;
180
181 default:
182 // Invalid reasonCode in received Disassociation frame
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530183 PELOGE(limLog(pMac, LOGE,
184 FL("received Disassoc frame with invalid reasonCode "
185 "%d from "MAC_ADDRESS_STR),
186 reasonCode, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700187 break;
188 }
189 }
190 else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
191 (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
192 ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
193 (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
194 (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
195 (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) ))
196 {
197 switch (reasonCode)
198 {
199 case eSIR_MAC_UNSPEC_FAILURE_REASON:
200 case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
201 case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON:
202 case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
203 case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
204 case eSIR_MAC_MIC_FAILURE_REASON:
205 case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
206 case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
207 case eSIR_MAC_RSN_IE_MISMATCH_REASON:
208 case eSIR_MAC_1X_AUTH_FAILURE_REASON:
Chet Lanctot186b5732013-03-18 10:26:30 -0700209 case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
Jeff Johnson295189b2012-06-20 16:38:30 -0700210 // Valid reasonCode in received Disassociation frame
211 break;
212
Srinivas Girigowdac03c5a82013-07-01 13:44:54 -0700213 case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
215 // Valid reasonCode in received Disassociation frame
216 // as long as we're not about to channel switch
Jeff Johnsone7245742012-09-05 17:12:55 -0700217 if(psessionEntry->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE)
Jeff Johnson295189b2012-06-20 16:38:30 -0700218 {
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530219 limLog(pMac, LOGE,
Jeff Johnson295189b2012-06-20 16:38:30 -0700220 FL("Ignoring disassoc frame due to upcoming "
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530221 "channel switch, from "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
Jeff Johnson295189b2012-06-20 16:38:30 -0700222 return;
223 }
224 break;
225
226 default:
227 // Invalid reasonCode in received Disassociation frame
228 // Log error and ignore the frame
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530229 PELOGE(limLog(pMac, LOGE,
230 FL("received Disassoc frame with invalid reasonCode "
231 "%d from "MAC_ADDRESS_STR), reasonCode,
232 MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 return;
234 }
235 }
236 else
237 {
238 // Received Disassociation frame in either IBSS
Srinivas Girigowdac03c5a82013-07-01 13:44:54 -0700239 // or un-known role. Log and ignore it
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530240 limLog(pMac, LOGE,
241 FL("received Disassoc frame with invalid reasonCode %d in role "
242 "%d in sme state %d from "MAC_ADDRESS_STR), reasonCode,
243 psessionEntry->limSystemRole, psessionEntry->limSmeState,
244 MAC_ADDR_ARRAY(pHdr->sa));
Jeff Johnson295189b2012-06-20 16:38:30 -0700245
246 return;
247 }
248
Jeff Johnson295189b2012-06-20 16:38:30 -0700249 if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
250 (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE))
251 {
252 /**
253 * Already in the process of deleting context for the peer
254 * and received Disassociation frame. Log and Ignore.
255 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530256 PELOGE(limLog(pMac, LOGE,
257 FL("received Disassoc frame in state %d from "MAC_ADDRESS_STR),
258 pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700259
260 return;
261 }
262
263 if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
264 {
265 /**
266 * Requesting STA is in some 'transient' state?
267 * Log error.
268 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530269 PELOGE(limLog(pMac, LOGE,
270 FL("received Disassoc frame from peer that is in state %X, addr "
271 MAC_ADDRESS_STR),
272 pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700273 } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
274
275 pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
276 pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
277
278 // Issue Disassoc Indication to SME.
Hema Aparna Medicharlaeef78fc2013-07-12 11:47:01 +0530279 vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr,
280 (tANI_U8 *) pStaDs->staAddr,
281 sizeof(tSirMacAddr));
Jeff Johnson295189b2012-06-20 16:38:30 -0700282 mlmDisassocInd.reasonCode =
283 (tANI_U8) pStaDs->mlmStaContext.disassocReason;
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
285
286 /* Update PE session Id */
287 mlmDisassocInd.sessionId = psessionEntry->peSessionId;
288
289 if (limIsReassocInProgress(pMac,psessionEntry)) {
290
291 /* If we're in the middle of ReAssoc and received disassoc from
292 * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
293 * failure result code. By design, SME will then issue "Disassoc"
294 * and cleanup will happen at that time.
295 */
Abhishek Singh6f9d2c82013-12-24 15:29:53 +0530296 PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting "
297 "for Reassoc Rsp"));)
Jeff Johnson295189b2012-06-20 16:38:30 -0700298
299 if (psessionEntry->limAssocResponseData) {
Hema Aparna Medicharlaeef78fc2013-07-12 11:47:01 +0530300 vos_mem_free(psessionEntry->limAssocResponseData);
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 psessionEntry->limAssocResponseData = NULL;
302 }
303
304 limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
305 return;
306 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700307
308 limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND,
309 (tANI_U32 *) &mlmDisassocInd);
310
311
312 // send eWNI_SME_DISASSOC_IND to SME
313 limSendSmeDisassocInd(pMac, pStaDs,psessionEntry);
314
315 return;
316} /*** end limProcessDisassocFrame() ***/
317