PageRenderTime 24ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/prima/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c

https://gitlab.com/jhalayashraj/nkernel
C | 345 lines | 201 code | 40 blank | 104 comment | 37 complexity | 2fd4cfae838b28bb255b8b2e372706e0 MD5 | raw file
  1. /*
  2. * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
  3. *
  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. * This file was originally distributed by Qualcomm Atheros, Inc.
  23. * under proprietary terms before Copyright ownership was assigned
  24. * to the Linux Foundation.
  25. */
  26. /*
  27. * This file limProcessDisassocFrame.cc contains the code
  28. * for processing Disassocation Frame.
  29. * Author: Chandra Modumudi
  30. * Date: 03/24/02
  31. * History:-
  32. * Date Modified by Modification Information
  33. * --------------------------------------------------------------------
  34. *
  35. */
  36. #include "palTypes.h"
  37. #include "wniApi.h"
  38. #include "sirApi.h"
  39. #include "aniGlobal.h"
  40. #include "wniCfg.h"
  41. #include "utilsApi.h"
  42. #include "limTypes.h"
  43. #include "limUtils.h"
  44. #include "limAssocUtils.h"
  45. #include "limSecurityUtils.h"
  46. #include "limSerDesUtils.h"
  47. #include "limSendMessages.h"
  48. #include "schApi.h"
  49. /**
  50. * limProcessDisassocFrame
  51. *
  52. *FUNCTION:
  53. * This function is called by limProcessMessageQueue() upon
  54. * Disassociation frame reception.
  55. *
  56. *LOGIC:
  57. *
  58. *ASSUMPTIONS:
  59. * DPH drops packets for STA with 'valid' bit in pStaDs set to '0'.
  60. *
  61. *NOTE:
  62. *
  63. * @param pMac - Pointer to Global MAC structure
  64. * @param *pRxPacketInfo - A pointer to Rx packet info structure
  65. * @return None
  66. */
  67. void
  68. limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession psessionEntry)
  69. {
  70. tANI_U8 *pBody;
  71. tANI_U16 aid, reasonCode;
  72. tpSirMacMgmtHdr pHdr;
  73. tpDphHashNode pStaDs;
  74. tLimMlmDisassocInd mlmDisassocInd;
  75. #ifdef WLAN_FEATURE_11W
  76. tANI_U32 frameLen;
  77. #endif
  78. pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
  79. pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo);
  80. if (limIsGroupAddr(pHdr->sa))
  81. {
  82. // Received Disassoc frame from a BC/MC address
  83. // Log error and ignore it
  84. PELOGE(limLog(pMac, LOG1,
  85. FL("received Disassoc frame from a BC/MC address"));)
  86. return;
  87. }
  88. if (limIsGroupAddr(pHdr->da) && !limIsAddrBC(pHdr->da))
  89. {
  90. // Received Disassoc frame for a MC address
  91. // Log error and ignore it
  92. PELOGE(limLog(pMac, LOG1,
  93. FL("received Disassoc frame for a MC address"));)
  94. return;
  95. }
  96. #ifdef WLAN_FEATURE_11W
  97. /* PMF: If this session is a PMF session, then ensure that this frame was protected */
  98. if(psessionEntry->limRmfEnabled && (WDA_GET_RX_DPU_FEEDBACK(pRxPacketInfo) & DPU_FEEDBACK_UNPROTECTED_ERROR))
  99. {
  100. PELOGE(limLog(pMac, LOG1, FL("received an unprotected disassoc from AP"));)
  101. // If the frame received is unprotected, forward it to the supplicant to initiate
  102. // an SA query
  103. frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
  104. //send the unprotected frame indication to SME
  105. limSendSmeUnprotectedMgmtFrameInd( pMac, pHdr->fc.subType,
  106. (tANI_U8*)pHdr, (frameLen + sizeof(tSirMacMgmtHdr)),
  107. psessionEntry->smeSessionId, psessionEntry);
  108. return;
  109. }
  110. #endif
  111. // Get reasonCode from Disassociation frame body
  112. reasonCode = sirReadU16(pBody);
  113. limLog(pMac, LOGE,
  114. FL("Received Disassoc frame for Addr: "MAC_ADDRESS_STR
  115. "(mlm state=%s, sme state=%d),"
  116. "with reason code %d from "MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->da),
  117. limMlmStateStr(psessionEntry->limMlmState), psessionEntry->limSmeState,
  118. reasonCode, MAC_ADDR_ARRAY(pHdr->sa));
  119. /**
  120. * Extract 'associated' context for STA, if any.
  121. * This is maintained by DPH and created by LIM.
  122. */
  123. pStaDs = dphLookupHashEntry(pMac, pHdr->sa, &aid, &psessionEntry->dph.dphHashTable);
  124. if (pStaDs == NULL)
  125. {
  126. /**
  127. * Disassociating STA is not associated.
  128. * Log error.
  129. */
  130. PELOGE(limLog(pMac, LOG1,
  131. FL("received Disassoc frame from STA that does not have context "
  132. "reasonCode=%d, addr "MAC_ADDRESS_STR),
  133. reasonCode,MAC_ADDR_ARRAY(pHdr->sa));)
  134. return;
  135. }
  136. if (limCheckDisassocDeauthAckPending(pMac, (tANI_U8*)pHdr->sa))
  137. {
  138. PELOGE(limLog(pMac, LOG1,
  139. FL("Ignore the DisAssoc received, while waiting "
  140. "for ack of disassoc/deauth"));)
  141. limCleanUpDisassocDeauthReq(pMac,(tANI_U8*)pHdr->sa, 1);
  142. return;
  143. }
  144. /** If we are in the Wait for ReAssoc Rsp state */
  145. if (limIsReassocInProgress(pMac,psessionEntry)) {
  146. /** If we had received the DisAssoc from,
  147. * a. the Current AP during ReAssociate to different AP in same ESS
  148. * b. Unknown AP
  149. * drop/ignore the DisAssoc received
  150. */
  151. if (!IS_REASSOC_BSSID(pMac,pHdr->sa,psessionEntry)) {
  152. PELOGE(limLog(pMac, LOGE, FL("Ignore the DisAssoc received, while "
  153. "Processing ReAssoc with different/unknown AP"));)
  154. return;
  155. }
  156. /** If the Disassoc is received from the new AP to which we tried to ReAssociate
  157. * Drop ReAssoc and Restore the Previous context( current connected AP).
  158. */
  159. if (!IS_CURRENT_BSSID(pMac, pHdr->sa,psessionEntry)) {
  160. PELOGE(limLog(pMac, LOGE, FL("received Disassoc from the New AP to "
  161. "which ReAssoc is sent "));)
  162. limRestorePreReassocState(pMac,
  163. eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
  164. return;
  165. }
  166. }
  167. if ( (psessionEntry->limSystemRole == eLIM_AP_ROLE) ||
  168. (psessionEntry->limSystemRole == eLIM_BT_AMP_AP_ROLE) )
  169. {
  170. switch (reasonCode)
  171. {
  172. case eSIR_MAC_UNSPEC_FAILURE_REASON:
  173. case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
  174. case eSIR_MAC_DISASSOC_LEAVING_BSS_REASON:
  175. case eSIR_MAC_MIC_FAILURE_REASON:
  176. case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
  177. case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
  178. case eSIR_MAC_RSN_IE_MISMATCH_REASON:
  179. case eSIR_MAC_1X_AUTH_FAILURE_REASON:
  180. // Valid reasonCode in received Disassociation frame
  181. break;
  182. default:
  183. // Invalid reasonCode in received Disassociation frame
  184. PELOGE(limLog(pMac, LOGE,
  185. FL("received Disassoc frame with invalid reasonCode "
  186. "%d from "MAC_ADDRESS_STR),
  187. reasonCode, MAC_ADDR_ARRAY(pHdr->sa));)
  188. break;
  189. }
  190. }
  191. else if ( ((psessionEntry->limSystemRole == eLIM_STA_ROLE) ||
  192. (psessionEntry->limSystemRole == eLIM_BT_AMP_STA_ROLE)) &&
  193. ((psessionEntry->limSmeState != eLIM_SME_WT_JOIN_STATE) &&
  194. (psessionEntry->limSmeState != eLIM_SME_WT_AUTH_STATE) &&
  195. (psessionEntry->limSmeState != eLIM_SME_WT_ASSOC_STATE) &&
  196. (psessionEntry->limSmeState != eLIM_SME_WT_REASSOC_STATE) ))
  197. {
  198. switch (reasonCode)
  199. {
  200. case eSIR_MAC_UNSPEC_FAILURE_REASON:
  201. case eSIR_MAC_DISASSOC_DUE_TO_INACTIVITY_REASON:
  202. case eSIR_MAC_DISASSOC_DUE_TO_DISABILITY_REASON:
  203. case eSIR_MAC_CLASS2_FRAME_FROM_NON_AUTH_STA_REASON:
  204. case eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON:
  205. case eSIR_MAC_MIC_FAILURE_REASON:
  206. case eSIR_MAC_4WAY_HANDSHAKE_TIMEOUT_REASON:
  207. case eSIR_MAC_GR_KEY_UPDATE_TIMEOUT_REASON:
  208. case eSIR_MAC_RSN_IE_MISMATCH_REASON:
  209. case eSIR_MAC_1X_AUTH_FAILURE_REASON:
  210. case eSIR_MAC_PREV_AUTH_NOT_VALID_REASON:
  211. // Valid reasonCode in received Disassociation frame
  212. break;
  213. case eSIR_MAC_DEAUTH_LEAVING_BSS_REASON:
  214. 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
  217. if(psessionEntry->gLimChannelSwitch.state != eLIM_CHANNEL_SWITCH_IDLE)
  218. {
  219. limLog(pMac, LOGE,
  220. FL("Ignoring disassoc frame due to upcoming "
  221. "channel switch, from "MAC_ADDRESS_STR),MAC_ADDR_ARRAY(pHdr->sa));
  222. return;
  223. }
  224. break;
  225. default:
  226. // Invalid reasonCode in received Disassociation frame
  227. // Log error and ignore the frame
  228. PELOGE(limLog(pMac, LOGE,
  229. FL("received Disassoc frame with invalid reasonCode "
  230. "%d from "MAC_ADDRESS_STR), reasonCode,
  231. MAC_ADDR_ARRAY(pHdr->sa));)
  232. return;
  233. }
  234. }
  235. else
  236. {
  237. // Received Disassociation frame in either IBSS
  238. // or un-known role. Log and ignore it
  239. limLog(pMac, LOG1,
  240. FL("received Disassoc frame with invalid reasonCode %d in role "
  241. "%d in sme state %d from "MAC_ADDRESS_STR), reasonCode,
  242. psessionEntry->limSystemRole, psessionEntry->limSmeState,
  243. MAC_ADDR_ARRAY(pHdr->sa));
  244. return;
  245. }
  246. if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) ||
  247. (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE))
  248. {
  249. /**
  250. * Already in the process of deleting context for the peer
  251. * and received Disassociation frame. Log and Ignore.
  252. */
  253. PELOGE(limLog(pMac, LOGE,
  254. FL("received Disassoc frame in state %d from "MAC_ADDRESS_STR
  255. ",isDisassocDeauthInProgress : %d\n"),
  256. pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa),
  257. pStaDs->isDisassocDeauthInProgress);)
  258. return;
  259. }
  260. if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
  261. {
  262. /**
  263. * Requesting STA is in some 'transient' state?
  264. * Log error.
  265. */
  266. if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE)
  267. pStaDs->mlmStaContext.updateContext = 1;
  268. PELOGE(limLog(pMac, LOGE,
  269. FL("received Disassoc frame from peer that is in state %d, addr "
  270. MAC_ADDRESS_STR),
  271. pStaDs->mlmStaContext.mlmState, MAC_ADDR_ARRAY(pHdr->sa));)
  272. } // if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE)
  273. pStaDs->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DISASSOC;
  274. pStaDs->mlmStaContext.disassocReason = (tSirMacReasonCodes) reasonCode;
  275. // Issue Disassoc Indication to SME.
  276. vos_mem_copy((tANI_U8 *) &mlmDisassocInd.peerMacAddr,
  277. (tANI_U8 *) pStaDs->staAddr,
  278. sizeof(tSirMacAddr));
  279. mlmDisassocInd.reasonCode =
  280. (tANI_U8) pStaDs->mlmStaContext.disassocReason;
  281. mlmDisassocInd.disassocTrigger = eLIM_PEER_ENTITY_DISASSOC;
  282. /* Update PE session Id */
  283. mlmDisassocInd.sessionId = psessionEntry->peSessionId;
  284. if (limIsReassocInProgress(pMac,psessionEntry)) {
  285. /* If we're in the middle of ReAssoc and received disassoc from
  286. * the ReAssoc AP, then notify SME by sending REASSOC_RSP with
  287. * failure result code. By design, SME will then issue "Disassoc"
  288. * and cleanup will happen at that time.
  289. */
  290. PELOGE(limLog(pMac, LOGE, FL("received Disassoc from AP while waiting "
  291. "for Reassoc Rsp"));)
  292. if (psessionEntry->limAssocResponseData) {
  293. vos_mem_free(psessionEntry->limAssocResponseData);
  294. psessionEntry->limAssocResponseData = NULL;
  295. }
  296. limRestorePreReassocState(pMac,eSIR_SME_REASSOC_REFUSED, reasonCode,psessionEntry);
  297. return;
  298. }
  299. limUpdateLostLinkParams(pMac, psessionEntry, pRxPacketInfo);
  300. limPostSmeMessage(pMac, LIM_MLM_DISASSOC_IND,
  301. (tANI_U32 *) &mlmDisassocInd);
  302. // send eWNI_SME_DISASSOC_IND to SME
  303. limSendSmeDisassocInd(pMac, pStaDs,psessionEntry);
  304. return;
  305. } /*** end limProcessDisassocFrame() ***/