blob: 2754cbb7309c16064e590636832c3b7c43803b17 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Anurag Chouhan6d760662016-02-20 16:05:43 +05302 * Copyright (c) 2012-2016 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 * This file lim_process_assoc_req_frame.cc contains the code
30 * for processing Re/Association Request Frame.
31 * Author: Chandra Modumudi
32 * Date: 03/18/02
33 * History:-
34 * Date Modified by Modification Information
35 * --------------------------------------------------------------------
36 * 05/26/10 js WPA handling in (Re)Assoc frames
37 *
38 */
39#include "cds_api.h"
40#include "ani_global.h"
41#include "wni_cfg.h"
42#include "sir_api.h"
43#include "cfg_api.h"
44
45#include "sch_api.h"
46#include "utils_api.h"
47#include "lim_types.h"
48#include "lim_utils.h"
49#include "lim_assoc_utils.h"
50#include "lim_security_utils.h"
51#include "lim_ser_des_utils.h"
52#include "lim_sta_hash_api.h"
53#include "lim_admit_control.h"
54#include "cds_packet.h"
55#include "lim_session_utils.h"
56
Anurag Chouhan6d760662016-02-20 16:05:43 +053057#include "qdf_types.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080058#include "cds_utils.h"
59
60/**
61 * lim_convert_supported_channels - Parses channel support IE
62 *
63 * @mac_ctx - A pointer to Global MAC structure
64 * @assoc_ind - A pointer to SME ASSOC/REASSOC IND
65 * @assoc_req - A pointer to ASSOC/REASSOC Request frame
66 *
67 * This function is called by lim_process_assoc_req_frame() to
68 * parse the channel support IE in the Assoc/Reassoc Request
69 * frame, and send relevant information in the SME_ASSOC_IND
70 *
71 * return None
72 */
73static void
74lim_convert_supported_channels(tpAniSirGlobal mac_ctx,
75 tpLimMlmAssocInd assoc_ind, tSirAssocReq *assoc_req)
76{
77 uint16_t i, j, index = 0;
78 uint8_t first_chn_no;
79 uint8_t chn_count;
80 uint8_t next_chn_no;
81 uint8_t channel_offset = 0;
82
83 if (assoc_req->supportedChannels.length >=
84 SIR_MAX_SUPPORTED_CHANNEL_LIST) {
85 lim_log(mac_ctx, LOG1,
86 FL("Number of supported channels:%d is more than MAX"),
87 assoc_req->supportedChannels.length);
88 assoc_ind->supportedChannels.numChnl = 0;
89 return;
90 }
91
92 for (i = 0; i < (assoc_req->supportedChannels.length); i++) {
93 /* Get First Channel Number */
94 first_chn_no =
95 assoc_req->supportedChannels.supportedChannels[i];
96 assoc_ind->supportedChannels.channelList[index] =
97 first_chn_no;
98 i++;
99 index++;
100
101 /* Get Number of Channels in a Subband */
102 chn_count =
103 assoc_req->supportedChannels.supportedChannels[i];
104 PELOG2(lim_log(mac_ctx, LOG2,
105 FL("Rcv assoc_req: chnl=%d, numOfChnl=%d "),
106 first_chn_no, chn_count);)
107 if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
108 PELOG2(lim_log(mac_ctx, LOGW,
109 FL("Channel count is more than max supported =%d "),
110 chn_count);)
111 assoc_ind->supportedChannels.numChnl = 0;
112 return;
113 }
114 if (chn_count <= 1)
115 continue;
116 next_chn_no = first_chn_no;
117 if (SIR_BAND_5_GHZ == lim_get_rf_band(first_chn_no))
118 channel_offset = SIR_11A_FREQUENCY_OFFSET;
119 else if (SIR_BAND_2_4_GHZ == lim_get_rf_band(first_chn_no))
120 channel_offset = SIR_11B_FREQUENCY_OFFSET;
121 else
122 continue;
123
124 for (j = 1; j < chn_count; j++) {
125 next_chn_no += channel_offset;
126 assoc_ind->supportedChannels.channelList[index]
127 = next_chn_no;
128 index++;
129 if (index >= SIR_MAX_SUPPORTED_CHANNEL_LIST) {
130 PELOG2(lim_log(mac_ctx, LOGW,
131 FL("Channel count is more than supported =%d "),
132 chn_count);)
133 assoc_ind->supportedChannels.numChnl = 0;
134 return;
135 }
136 }
137 }
138
139 assoc_ind->supportedChannels.numChnl = (uint8_t) index;
140 PELOG2(lim_log(mac_ctx, LOG2,
141 FL("Send AssocInd to WSM: minPwr %d, maxPwr %d, numChnl %d"),
142 assoc_ind->powerCap.minTxPower,
143 assoc_ind->powerCap.maxTxPower,
144 assoc_ind->supportedChannels.numChnl);)
145}
146
147/**---------------------------------------------------------------
148 \fn lim_check_sta_in_pe_entries
149 \brief This function is called by lim_process_assoc_req_frame()
150 \ to check if STA entry already exists in any of the
151 \ PE entries of the AP. If it exists, deauth will be
152 \ sent on that session and the STA deletion will
153 \ happen. After this, the ASSOC request will be
154 \ processed
155 \
156 \param pMac - A pointer to Global MAC structure
157 \param pHdr - A pointer to the MAC header
158 \return None
159 ------------------------------------------------------------------*/
160void lim_check_sta_in_pe_entries(tpAniSirGlobal pMac, tpSirMacMgmtHdr pHdr)
161{
162 uint8_t i;
163 uint16_t assocId = 0;
164 tpDphHashNode pStaDs = NULL;
165 tpPESession psessionEntry = NULL;
166
167 for (i = 0; i < pMac->lim.maxBssId; i++) {
168 if ((&pMac->lim.gpSession[i] != NULL) &&
169 (pMac->lim.gpSession[i].valid) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530170 (pMac->lim.gpSession[i].pePersona == QDF_SAP_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171
172 psessionEntry = &pMac->lim.gpSession[i];
173 pStaDs = dph_lookup_hash_entry(pMac, pHdr->sa, &assocId,
174 &psessionEntry->dph.
175 dphHashTable);
176 if (pStaDs
177#ifdef WLAN_FEATURE_11W
178 && !pStaDs->rmfEnabled
179#endif
180 ) {
181 lim_log(pMac, LOGE,
182 FL
183 ("Sending Deauth and Deleting existing STA entry: "
184 MAC_ADDRESS_STR),
185 MAC_ADDR_ARRAY(psessionEntry->
186 selfMacAddr));
187 lim_send_deauth_mgmt_frame(pMac,
188 eSIR_MAC_UNSPEC_FAILURE_REASON,
189 (uint8_t *) pHdr->sa,
190 psessionEntry, false);
191 lim_trigger_sta_deletion(pMac, pStaDs,
192 psessionEntry);
193 break;
194 }
195 }
196 }
197}
198
199/**---------------------------------------------------------------
200 \fn lim_process_assoc_req_frame
201 \brief This function is called by limProcessMessageQueue()
202 \ upon Re/Association Request frame reception in
203 \ BTAMP AP or Soft AP role.
204 \
205 \param pMac
206 \param *pRxPacketInfo - A pointer to Buffer descriptor + associated PDUs
207 \param subType - Indicates whether it is Association Request(=0)
208 \ or Reassociation Request(=1) frame
209 \return None
210 ------------------------------------------------------------------*/
211void
212lim_process_assoc_req_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
213 uint8_t subType, tpPESession psessionEntry)
214{
215 uint8_t updateContext;
216 uint8_t *pBody;
217 uint16_t peerIdx, temp;
218 uint32_t val;
219 int32_t framelen;
220 tSirRetStatus status;
221 tpSirMacMgmtHdr pHdr;
222 struct tLimPreAuthNode *pStaPreAuthContext;
223 tAniAuthType authType;
224 tSirMacCapabilityInfo localCapabilities;
225 tpDphHashNode pStaDs = NULL;
226 tpSirAssocReq pAssocReq, pTempAssocReq;
227 tLimMlmStates mlmPrevState;
228 tDot11fIERSN Dot11fIERSN;
229 tDot11fIEWPA Dot11fIEWPA;
230 uint32_t phyMode;
231 tHalBitVal qosMode;
232 tHalBitVal wsmMode, wmeMode;
233 uint8_t *wpsIe = NULL;
234 uint8_t *ht_cap_ie = NULL;
235 tSirMacRateSet basicRates;
236 uint8_t i = 0, j = 0;
237 bool pmfConnection = false;
238#ifdef WLAN_FEATURE_11W
239 tPmfSaQueryTimerId timerId;
240 uint32_t retryInterval;
241#endif
242 uint16_t assoc_id = 0;
243 bool assoc_req_copied = false;
244
245 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
246
247 limGetQosMode(psessionEntry, &qosMode);
248
249 pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
250 framelen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
251
252 lim_log(pMac, LOG1,
253 FL("Received %s Req Frame on sessionid: %d systemrole %d"
254 " limMlmState %d from: " MAC_ADDRESS_STR),
255 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
256 psessionEntry->peSessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
257 psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->sa));
258
259 if (LIM_IS_STA_ROLE(psessionEntry) ||
260 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
261 lim_log(pMac, LOGE,
262 FL("received unexpected ASSOC REQ on sessionid: %d "
263 "sys subType=%d for role=%d from: " MAC_ADDRESS_STR),
264 psessionEntry->peSessionId, subType,
265 GET_LIM_SYSTEM_ROLE(psessionEntry),
266 MAC_ADDR_ARRAY(pHdr->sa));
267 sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG3,
268 WMA_GET_RX_MPDU_DATA(pRxPacketInfo), framelen);
269 return;
270 }
271
272 /*
273 * If a STA is already present in DPH and it
274 * is initiating a Assoc re-transmit, do not
275 * process it. This can happen when first Assoc Req frame
276 * is received but ACK lost at STA side. The ACK for this
277 * dropped Assoc Req frame should be sent by HW. Host simply
278 * does not process it once the entry for the STA is already
279 * present in DPH.
280 */
281 pStaDs = dph_lookup_hash_entry(pMac, pHdr->sa, &assoc_id,
282 &psessionEntry->dph.dphHashTable);
Masti, Narayanraddif0493822015-08-10 11:11:24 +0530283 if ((NULL != pStaDs)) {
284 if (pHdr->fc.retry > 0) {
285 lim_log(pMac, LOGE,
286 FL("STA is initiating Assoc Req after ACK lost. Do not process"
287 " sessionid: %d sys subType=%d for role=%d from: "
288 MAC_ADDRESS_STR), psessionEntry->peSessionId,
289 subType, GET_LIM_SYSTEM_ROLE(psessionEntry),
290 MAC_ADDR_ARRAY(pHdr->sa));
Masti, Narayanraddi605b5362015-11-02 11:42:28 +0530291 } else if (!pStaDs->rmfEnabled) {
292 /* Do this only for non PMF case.
293 *
Masti, Narayanraddif0493822015-08-10 11:11:24 +0530294 * STA might have missed the assoc response,
295 * so it is sending assoc request frame again.
296 */
297 lim_send_assoc_rsp_mgmt_frame(pMac, eSIR_SUCCESS,
298 pStaDs->assocId, pStaDs->staAddr,
299 pStaDs->mlmStaContext.subType, pStaDs,
300 psessionEntry);
301 lim_log(pMac, LOGE,
302 FL("DUT already received an assoc request frame "
303 "and STA is sending another assoc req.So, do not "
304 "Process sessionid: %d sys subType=%d for role=%d "
305 "from: "MAC_ADDRESS_STR),
306 psessionEntry->peSessionId, subType,
307 psessionEntry->limSystemRole,
308 MAC_ADDR_ARRAY(pHdr->sa));
309 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800310 return;
311 }
312
313 lim_check_sta_in_pe_entries(pMac, pHdr);
314
315 /* Get pointer to Re/Association Request frame body */
316 pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
317
318 if (lim_is_group_addr(pHdr->sa)) {
319 /* Received Re/Assoc Req frame from a BC/MC address */
320 /* Log error and ignore it */
321 lim_log(pMac, LOGE,
322 FL("Received %s Req on sessionid: %d frame from a "
323 "BC/MC address" MAC_ADDRESS_STR),
324 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
325 psessionEntry->peSessionId, MAC_ADDR_ARRAY(pHdr->sa));
326 return;
327 }
328
329 sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG2, (uint8_t *) pBody, framelen);
330
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530331 if (!qdf_mem_cmp((uint8_t *) pHdr->sa, (uint8_t *) pHdr->da,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800332 (uint8_t) (sizeof(tSirMacAddr)))) {
333 lim_log(pMac, LOGE,
334 FL("Rejected Assoc Req frame Since same mac as"
335 " SAP/GO"));
336 lim_send_assoc_rsp_mgmt_frame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS,
337 1, pHdr->sa, subType, 0,
338 psessionEntry);
339 return;
340 }
341 /* If TKIP counter measures active send Assoc Rsp frame to station with eSIR_MAC_MIC_FAILURE_REASON */
342 if (psessionEntry->bTkipCntrMeasActive &&
343 LIM_IS_AP_ROLE(psessionEntry)) {
344 lim_log(pMac, LOGE, FL("TKIP counter measure is active"));
345 lim_send_assoc_rsp_mgmt_frame(pMac,
346 eSIR_MAC_MIC_FAILURE_REASON,
347 1, pHdr->sa, subType,
348 0, psessionEntry);
349 return;
350 }
351 /* Allocate memory for the Assoc Request frame */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530352 pAssocReq = qdf_mem_malloc(sizeof(*pAssocReq));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800353 if (NULL == pAssocReq) {
354 lim_log(pMac, LOGP, FL("Allocate Memory failed in assoc_req"));
355 return;
356 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530357 qdf_mem_set((void *)pAssocReq, sizeof(*pAssocReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358
359 /* Parse Assoc Request frame */
360 if (subType == LIM_ASSOC)
361 status =
362 sir_convert_assoc_req_frame2_struct(pMac, pBody, framelen,
363 pAssocReq);
364 else
365 status =
366 sir_convert_reassoc_req_frame2_struct(pMac, pBody, framelen,
367 pAssocReq);
368
369 if (status != eSIR_SUCCESS) {
370 lim_log(pMac, LOGE,
371 FL("Parse error AssocRequest, length=%d from "
372 MAC_ADDRESS_STR), framelen, MAC_ADDR_ARRAY(pHdr->sa));
373 lim_send_assoc_rsp_mgmt_frame(pMac, eSIR_MAC_UNSPEC_FAILURE_STATUS,
374 1, pHdr->sa, subType, 0,
375 psessionEntry);
376 goto error;
377 }
378
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530379 pAssocReq->assocReqFrame = qdf_mem_malloc(framelen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800380 if (NULL == pAssocReq->assocReqFrame) {
381 lim_log(pMac, LOGE,
382 FL("Unable to allocate memory for the assoc req, "
383 "length=%d from "), framelen);
384 goto error;
385 }
386
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530387 qdf_mem_copy((uint8_t *) pAssocReq->assocReqFrame,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 (uint8_t *) pBody, framelen);
389 pAssocReq->assocReqFrameLength = framelen;
390
391 if (cfg_get_capability_info(pMac, &temp, psessionEntry) != eSIR_SUCCESS) {
392 lim_log(pMac, LOGP, FL("could not retrieve Capabilities"));
393 goto error;
394 }
395 lim_copy_u16((uint8_t *) &localCapabilities, temp);
396
Anurag Chouhan6d760662016-02-20 16:05:43 +0530397 if (lim_compare_capabilities(pMac, pAssocReq,
398 &localCapabilities, psessionEntry) ==
399 false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 lim_log(pMac, LOGE, FL("local caps mismatch received caps"));
401 lim_log(pMac, LOGE, FL("Received %s Req with unsupported "
402 "capabilities from" MAC_ADDRESS_STR),
403 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
404 MAC_ADDR_ARRAY(pHdr->sa));
405 /**
406 * Capabilities of requesting STA does not match with
407 * local capabilities. Respond with 'unsupported capabilities'
408 * status code.
409 */
410 lim_send_assoc_rsp_mgmt_frame(pMac,
411 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
412 1,
413 pHdr->sa, subType, 0, psessionEntry);
414
415 goto error;
416 }
417
418 updateContext = false;
419
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530420 if (lim_cmp_ssid(&pAssocReq->ssId, psessionEntry) != false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 lim_log(pMac, LOGE,
422 FL("Received %s Req with unmatched ssid ( Received"
423 " SSID: %.*s current SSID: %.*s ) from "
424 MAC_ADDRESS_STR),
425 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
426 pAssocReq->ssId.length, pAssocReq->ssId.ssId,
427 psessionEntry->ssId.length, psessionEntry->ssId.ssId,
428 MAC_ADDR_ARRAY(pHdr->sa));
429
430 /**
431 * Received Re/Association Request with either
432 * Broadcast SSID OR with SSID that does not
433 * match with local one.
434 * Respond with unspecified status code.
435 */
436 lim_send_assoc_rsp_mgmt_frame(pMac,
437 eSIR_MAC_UNSPEC_FAILURE_STATUS,
438 1,
439 pHdr->sa, subType, 0, psessionEntry);
440
441 goto error;
442 }
443
444 /***************************************************************
445 ** Verify if the requested rates are available in supported rate
446 ** set or Extended rate set. Some APs are adding basic rates in
447 ** Extended rateset IE
448 ***************************************************************/
449 basicRates.numRates = 0;
450
451 for (i = 0;
452 i < pAssocReq->supportedRates.numRates
453 && (i < SIR_MAC_RATESET_EID_MAX); i++) {
454 basicRates.rate[i] = pAssocReq->supportedRates.rate[i];
455 basicRates.numRates++;
456 }
457
458 for (j = 0;
459 (j < pAssocReq->extendedRates.numRates)
460 && (i < SIR_MAC_RATESET_EID_MAX); i++, j++) {
461 basicRates.rate[i] = pAssocReq->extendedRates.rate[j];
462 basicRates.numRates++;
463 }
464 if (lim_check_rx_basic_rates(pMac, basicRates, psessionEntry) == false) {
465 lim_log(pMac, LOGE, FL("Received %s Req with unsupported "
466 "rates from" MAC_ADDRESS_STR),
467 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
468 MAC_ADDR_ARRAY(pHdr->sa));
469 /**
470 * Requesting STA does not support ALL BSS basic
471 * rates. Respond with 'basic rates not supported'
472 * status code.
473 */
474 lim_send_assoc_rsp_mgmt_frame(pMac,
475 eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
476 1,
477 pHdr->sa, subType, 0, psessionEntry);
478
479 goto error;
480 }
481
482 if (LIM_IS_AP_ROLE(psessionEntry) &&
483 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY) &&
Anurag Chouhan6d760662016-02-20 16:05:43 +0530484 (pAssocReq->HTCaps.present)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800485 lim_log(pMac, LOGE,
486 FL("SOFTAP was in 11G only mode, rejecting legacy "
487 "STA : " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
488 lim_send_assoc_rsp_mgmt_frame(pMac,
489 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
490 1, pHdr->sa, subType, 0,
491 psessionEntry);
492 goto error;
493
494 } /* end if phyMode == 11G_only */
495
496 if (LIM_IS_AP_ROLE(psessionEntry) &&
497 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N_ONLY) &&
498 (!pAssocReq->HTCaps.present)) {
499 lim_log(pMac, LOGE,
500 FL("SOFTAP was in 11N only mode, rejecting legacy "
501 "STA : " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
502 lim_send_assoc_rsp_mgmt_frame(pMac,
503 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
504 1, pHdr->sa, subType, 0,
505 psessionEntry);
506 goto error;
507 } /* end if PhyMode == 11N_only */
508
509 if (LIM_IS_AP_ROLE(psessionEntry) &&
510 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC_ONLY) &&
511 (!pAssocReq->VHTCaps.present)) {
512 lim_send_assoc_rsp_mgmt_frame(pMac,
513 eSIR_MAC_CAPABILITIES_NOT_SUPPORTED_STATUS,
514 1, pHdr->sa, subType, 0,
515 psessionEntry);
516 lim_log(pMac, LOGE, FL("SOFTAP was in 11AC only mode, reject"));
517 goto error;
518 } /* end if PhyMode == 11AC_only */
519
520 /* Spectrum Management (11h) specific checks */
521 if (localCapabilities.spectrumMgt) {
522 tSirRetStatus status = eSIR_SUCCESS;
523
524 /* If station is 11h capable, then it SHOULD send all mandatory
525 * IEs in assoc request frame. Let us verify that
526 */
527 if (pAssocReq->capabilityInfo.spectrumMgt) {
528 if (!
529 ((pAssocReq->powerCapabilityPresent)
530 && (pAssocReq->supportedChannelsPresent))) {
531 /* One or more required information elements are missing, log the peers error */
532 if (!pAssocReq->powerCapabilityPresent) {
533 lim_log(pMac, LOG1,
534 FL
535 ("LIM Info: Missing Power capability "
536 "IE in %s Req from "
537 MAC_ADDRESS_STR),
538 (LIM_ASSOC ==
539 subType) ? "Assoc" : "ReAssoc",
540 MAC_ADDR_ARRAY(pHdr->sa));
541 }
542 if (!pAssocReq->supportedChannelsPresent) {
543 lim_log(pMac, LOGW,
544 FL
545 ("LIM Info: Missing Supported channel "
546 "IE in %s Req from "
547 MAC_ADDRESS_STR),
548 (LIM_ASSOC ==
549 subType) ? "Assoc" : "ReAssoc",
550 MAC_ADDR_ARRAY(pHdr->sa));
551
552 }
553 } else {
554 /* Assoc request has mandatory fields */
555 status =
556 lim_is_dot11h_power_capabilities_in_range(pMac,
557 pAssocReq,
558 psessionEntry);
559 if (eSIR_SUCCESS != status) {
560 lim_log(pMac, LOGW,
561 FL("LIM Info: MinTxPower(STA) > "
562 "MaxTxPower(AP) in %s Req from "
563 MAC_ADDRESS_STR),
564 (LIM_ASSOC ==
565 subType) ? "Assoc" : "ReAssoc",
566 MAC_ADDR_ARRAY(pHdr->sa));
567
568 }
569 status =
570 lim_is_dot11h_supported_channels_valid(pMac,
571 pAssocReq);
572 if (eSIR_SUCCESS != status) {
573 lim_log(pMac, LOGW,
574 FL("LIM Info: wrong supported "
575 "channels (STA) in %s Req from "
576 MAC_ADDRESS_STR),
577 (LIM_ASSOC ==
578 subType) ? "Assoc" : "ReAssoc",
579 MAC_ADDR_ARRAY(pHdr->sa));
580
581 }
582 /* IEs are valid, use them if needed */
583 }
584 } /* if(assoc.capabilityInfo.spectrumMgt) */
585 else {
586 /* As per the capabiities, the spectrum management is not enabled on the station
587 * The AP may allow the associations to happen even if spectrum management is not
588 * allowed, if the transmit power of station is below the regulatory maximum
589 */
590
591 /* TODO: presently, this is not handled. In the current implemetation, the AP would
592 * allow the station to associate even if it doesn't support spectrum management.
593 */
594 }
595 } /* end of spectrum management related processing */
596
597 if ((pAssocReq->HTCaps.present)
598 && (lim_check_mcs_set(pMac, pAssocReq->HTCaps.supportedMCSSet) ==
599 false)) {
600 lim_log(pMac, LOGE,
601 FL("received %s req with unsupported"
602 "MCS Rate Set from " MAC_ADDRESS_STR),
603 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
604 MAC_ADDR_ARRAY(pHdr->sa));
605
606 /**
607 * Requesting STA does not support ALL BSS MCS basic Rate set rates.
608 * Spec does not define any status code for this scenario.
609 */
610 lim_send_assoc_rsp_mgmt_frame(pMac,
611 eSIR_MAC_OUTSIDE_SCOPE_OF_SPEC_STATUS,
612 1,
613 pHdr->sa, subType, 0, psessionEntry);
614
615 goto error;
616 }
617
618 if (phyMode == WNI_CFG_PHY_MODE_11G) {
619
620 if (wlan_cfg_get_int(pMac, WNI_CFG_11G_ONLY_POLICY, &val) !=
621 eSIR_SUCCESS) {
622 lim_log(pMac, LOGP,
623 FL("could not retrieve 11g-only flag"));
624 goto error;
625 }
626
627 if (!pAssocReq->extendedRatesPresent && val) {
628 /**
629 * Received Re/Association Request from
630 * 11b STA when 11g only policy option
631 * is set.
632 * Reject with unspecified status code.
633 */
634 lim_send_assoc_rsp_mgmt_frame(pMac,
635 eSIR_MAC_BASIC_RATES_NOT_SUPPORTED_STATUS,
636 1,
637 pHdr->sa,
638 subType, 0, psessionEntry);
639
640 lim_log(pMac, LOGE,
641 FL("Rejecting Re/Assoc req from 11b STA: "));
642 lim_print_mac_addr(pMac, pHdr->sa, LOGW);
643
644#ifdef WLAN_DEBUG
645 pMac->lim.gLim11bStaAssocRejectCount++;
646#endif
647 goto error;
648 }
649 }
650
651 /* Check for 802.11n HT caps compatibility; are HT Capabilities */
652 /* turned on in lim? */
653 if (psessionEntry->htCapability) {
654 /* There are; are they turned on in the STA? */
655 if (pAssocReq->HTCaps.present) {
656 /* The station *does* support 802.11n HT capability... */
657
658 lim_log(pMac, LOG1, FL("AdvCodingCap:%d ChaWidthSet:%d "
659 "PowerSave:%d greenField:%d "
660 "shortGI20:%d shortGI40:%d"
661 "txSTBC:%d rxSTBC:%d delayBA:%d"
662 "maxAMSDUsize:%d DSSS/CCK:%d "
663 "PSMP:%d stbcCntl:%d lsigTXProt:%d"),
664 pAssocReq->HTCaps.advCodingCap,
665 pAssocReq->HTCaps.supportedChannelWidthSet,
666 pAssocReq->HTCaps.mimoPowerSave,
667 pAssocReq->HTCaps.greenField,
668 pAssocReq->HTCaps.shortGI20MHz,
669 pAssocReq->HTCaps.shortGI40MHz,
670 pAssocReq->HTCaps.txSTBC,
671 pAssocReq->HTCaps.rxSTBC,
672 pAssocReq->HTCaps.delayedBA,
673 pAssocReq->HTCaps.maximalAMSDUsize,
674 pAssocReq->HTCaps.dsssCckMode40MHz,
675 pAssocReq->HTCaps.psmp,
676 pAssocReq->HTCaps.stbcControlFrame,
677 pAssocReq->HTCaps.lsigTXOPProtection);
678
679 /* Make sure the STA's caps are compatible with our own: */
680 /* 11.15.2 Support of DSSS/CCK in 40 MHz */
681 /* the AP shall refuse association requests from an HT STA that has the DSSS/CCK */
682 /* Mode in 40 MHz subfield set to 1; */
683 }
684 } /* End if on HT caps turned on in lim. */
685
686 /* Clear the buffers so that frame parser knows that there isn't a previously decoded IE in these buffers */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530687 qdf_mem_set((uint8_t *) &Dot11fIERSN, sizeof(Dot11fIERSN), 0);
688 qdf_mem_set((uint8_t *) &Dot11fIEWPA, sizeof(Dot11fIEWPA), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800689
690 /* if additional IE is present, check if it has WscIE */
691 if (pAssocReq->addIEPresent && pAssocReq->addIE.length)
692 wpsIe =
693 limGetWscIEPtr(pMac, pAssocReq->addIE.addIEdata,
694 pAssocReq->addIE.length);
695 else {
696 lim_log(pMac, LOG1, FL("Assoc req addIEPresent = %d "
697 "addIE length = %d"),
698 pAssocReq->addIEPresent, pAssocReq->addIE.length);
699 }
700 /* when wpsIe is present, RSN/WPA IE is ignored */
701 if (wpsIe == NULL) {
702 /** check whether as RSN IE is present */
703 if (LIM_IS_AP_ROLE(psessionEntry) &&
704 psessionEntry->pLimStartBssReq->privacy &&
705 psessionEntry->pLimStartBssReq->rsnIE.length) {
706 lim_log(pMac, LOG1,
707 FL("RSN enabled auth, Re/Assoc req from STA: "
708 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pHdr->sa));
709 if (pAssocReq->rsnPresent) {
710 if (pAssocReq->rsn.length) {
711 /* Unpack the RSN IE */
712 dot11f_unpack_ie_rsn(pMac,
713 &pAssocReq->rsn.
714 info[0],
715 pAssocReq->rsn.length,
716 &Dot11fIERSN);
717
718 /* Check RSN version is supported or not */
719 if (SIR_MAC_OUI_VERSION_1 ==
720 Dot11fIERSN.version) {
721 /* check the groupwise and pairwise cipher suites */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530722 status = lim_check_rx_rsn_ie_match(pMac,
723 Dot11fIERSN,
724 psessionEntry,
725 pAssocReq->
726 HTCaps.present,
727 &pmfConnection);
728 if (eSIR_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 lim_log(pMac, LOGE,
730 FL("RSN Mismatch."
731 "Rejecting Re/Assoc req from "
732 "STA: "
733 MAC_ADDRESS_STR),
734 MAC_ADDR_ARRAY
735 (pHdr->sa));
736
737 /* some IE is not properly sent */
738 /* received Association req frame with RSN IE but length is 0 */
739 lim_send_assoc_rsp_mgmt_frame
740 (pMac, status, 1,
741 pHdr->sa, subType,
742 0, psessionEntry);
743
744 goto error;
745
746 }
747 } else {
748 lim_log(pMac, LOGE,
749 FL("RSN length not correct."
750 "Rejecting Re/Assoc req from "
751 "STA: "
752 MAC_ADDRESS_STR),
753 MAC_ADDR_ARRAY(pHdr->
754 sa));
755
756 /* received Association req frame with RSN IE version wrong */
757 lim_send_assoc_rsp_mgmt_frame(pMac,
758 eSIR_MAC_UNSUPPORTED_RSN_IE_VERSION_STATUS,
759 1,
760 pHdr->
761 sa,
762 subType,
763 0,
764 psessionEntry);
765 goto error;
766
767 }
768 } else {
769 lim_log(pMac, LOGW,
770 FL
771 ("Rejecting Re/Assoc req from STA:"
772 MAC_ADDRESS_STR),
773 MAC_ADDR_ARRAY(pHdr->sa));
774 /* received Association req frame with RSN IE but length is 0 */
775 lim_send_assoc_rsp_mgmt_frame(pMac,
776 eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
777 1,
778 pHdr->sa,
779 subType, 0,
780 psessionEntry);
781
782 goto error;
783
784 }
785 } /* end - if(pAssocReq->rsnPresent) */
786 if ((!pAssocReq->rsnPresent) && pAssocReq->wpaPresent) {
787 /* Unpack the WPA IE */
788 if (pAssocReq->wpa.length) {
789 dot11f_unpack_ie_wpa(pMac, &pAssocReq->wpa.info[4], /* OUI is not taken care */
790 pAssocReq->wpa.length,
791 &Dot11fIEWPA);
792 /* check the groupwise and pairwise cipher suites */
Anurag Chouhan6d760662016-02-20 16:05:43 +0530793 status = lim_check_rx_wpa_ie_match(pMac,
794 Dot11fIEWPA,
795 psessionEntry,
796 pAssocReq->
797 HTCaps.
798 present);
799 if (eSIR_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 lim_log(pMac, LOGW,
801 FL("WPA IE mismatch"
802 "Rejecting Re/Assoc req from "
803 "STA: "
804 MAC_ADDRESS_STR),
805 MAC_ADDR_ARRAY(pHdr->
806 sa));
807 /* received Association req frame with WPA IE but mismatch */
808 lim_send_assoc_rsp_mgmt_frame(pMac,
809 status,
810 1,
811 pHdr->
812 sa,
813 subType,
814 0,
815 psessionEntry);
816 goto error;
817
818 }
819 } else {
820 lim_log(pMac, LOGW,
821 FL("WPA len incorrect."
822 "Rejecting Re/Assoc req from"
823 "STA: "MAC_ADDRESS_STR),
824 MAC_ADDR_ARRAY(pHdr->sa));
825 /* received Association req frame with invalid WPA IE */
826 lim_send_assoc_rsp_mgmt_frame(pMac,
827 eSIR_MAC_INVALID_INFORMATION_ELEMENT_STATUS,
828 1,
829 pHdr->sa,
830 subType, 0,
831 psessionEntry);
832
833 goto error;
834 } /* end - if(pAssocReq->wpa.length) */
835 } /* end - if(pAssocReq->wpaPresent) */
836 }
837 /* end of if(psessionEntry->pLimStartBssReq->privacy
838 && psessionEntry->pLimStartBssReq->rsnIE->length) */
839 } /* end of if( ! pAssocReq->wscInfo.present ) */
840 else {
841 lim_log(pMac, LOG1, FL("Assoc req WSE IE is present"));
842 }
843
844 /**
845 * Extract 'associated' context for STA, if any.
846 * This is maintained by DPH and created by LIM.
847 */
848 pStaDs =
849 dph_lookup_hash_entry(pMac, pHdr->sa, &peerIdx,
850 &psessionEntry->dph.dphHashTable);
851
852 /* / Extract pre-auth context for the STA, if any. */
853 pStaPreAuthContext = lim_search_pre_auth_list(pMac, pHdr->sa);
854
855 if (pStaDs == NULL) {
856 /* / Requesting STA is not currently associated */
857 if (pe_get_current_stas_count(pMac) ==
858 pMac->lim.gLimAssocStaLimit) {
859 /**
860 * Maximum number of STAs that AP can handle reached.
861 * Send Association response to peer MAC entity
862 */
863 lim_log(pMac, LOGE, FL("Max Sta count reached : %d"),
864 pMac->lim.maxStation);
865 lim_reject_association(pMac, pHdr->sa,
866 subType, false,
867 (tAniAuthType) 0, 0,
868 false,
869 (tSirResultCodes)
870 eSIR_MAC_UNSPEC_FAILURE_STATUS,
871 psessionEntry);
872
873 goto error;
874 }
875 /* / Check if STA is pre-authenticated. */
876 if ((pStaPreAuthContext == NULL) ||
877 (pStaPreAuthContext &&
878 (pStaPreAuthContext->mlmState !=
879 eLIM_MLM_AUTHENTICATED_STATE))) {
880 /**
881 * STA is not pre-authenticated yet requesting
882 * Re/Association before Authentication.
883 * OR STA is in the process of getting authenticated
884 * and sent Re/Association request.
885 * Send Deauthentication frame with 'prior
886 * authentication required' reason code.
887 */
888 lim_send_deauth_mgmt_frame(pMac, eSIR_MAC_STA_NOT_PRE_AUTHENTICATED_REASON, /* =9 */
889 pHdr->sa, psessionEntry, false);
890
891 lim_log(pMac, LOGE,
892 FL("received %s req on sessionid: %d from STA "
893 "that does not have pre-auth context"
894 MAC_ADDRESS_STR),
895 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
896 psessionEntry->peSessionId,
897 MAC_ADDR_ARRAY(pHdr->sa));
898 goto error;
899 }
900 /* / Delete 'pre-auth' context of STA */
901 authType = pStaPreAuthContext->authType;
902 lim_delete_pre_auth_node(pMac, pHdr->sa);
903
904 /* All is well. Assign AID (after else part) */
905
906 } /* if (pStaDs == NULL) */
907 else {
908 /* STA context does exist for this STA */
909
910 if (pStaDs->mlmStaContext.mlmState !=
911 eLIM_MLM_LINK_ESTABLISHED_STATE) {
912 /**
913 * Requesting STA is in some 'transient' state?
914 * Ignore the Re/Assoc Req frame by incrementing
915 * debug counter & logging error.
916 */
917 if (subType == LIM_ASSOC) {
918
919#ifdef WLAN_DEBUG
920 pMac->lim.gLimNumAssocReqDropInvldState++;
921#endif
922 lim_log(pMac, LOGE,
923 FL("received Assoc req in state "
924 "%X from "),
925 pStaDs->mlmStaContext.mlmState);
926 } else {
927#ifdef WLAN_DEBUG
928 pMac->lim.gLimNumReassocReqDropInvldState++;
929#endif
930 lim_log(pMac, LOGE,
931 FL("received ReAssoc req in state %X"
932 " from "),
933 pStaDs->mlmStaContext.mlmState);
934 }
935 lim_print_mac_addr(pMac, pHdr->sa, LOG1);
936 lim_print_mlm_state(pMac, LOG1,
937 (tLimMlmStates) pStaDs->mlmStaContext.
938 mlmState);
939
940 goto error;
941 } /* if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) */
942
943 /* STA sent association Request frame while already in
944 * 'associated' state */
945
946#ifdef WLAN_FEATURE_11W
947 lim_log(pMac, LOG1,
948 FL
949 ("Re/Assoc request from station that is already associated"));
950 lim_log(pMac, LOG1, FL("PMF enabled %d, SA Query state %d"),
951 pStaDs->rmfEnabled, pStaDs->pmfSaQueryState);
952 if (pStaDs->rmfEnabled) {
953 switch (pStaDs->pmfSaQueryState) {
954
955 /* start SA Query procedure, respond to Association Request */
956 /* with try again later */
957 case DPH_SA_QUERY_NOT_IN_PROGRESS:
958 /*
959 * We should reset the retry counter before we start
960 * the SA query procedure, otherwise in next set of SA query
961 * procedure we will end up using the stale value.
962 */
963 pStaDs->pmfSaQueryRetryCount = 0;
964 lim_send_assoc_rsp_mgmt_frame(pMac,
965 eSIR_MAC_TRY_AGAIN_LATER,
966 1, pHdr->sa, subType,
967 pStaDs, psessionEntry);
968 lim_send_sa_query_request_frame(pMac,
969 (uint8_t *) &
970 (pStaDs->
971 pmfSaQueryCurrentTransId),
972 pHdr->sa,
973 psessionEntry);
974 pStaDs->pmfSaQueryStartTransId =
975 pStaDs->pmfSaQueryCurrentTransId;
976 pStaDs->pmfSaQueryCurrentTransId++;
977
978 /* start timer for SA Query retry */
979 if (tx_timer_activate(&pStaDs->pmfSaQueryTimer)
980 != TX_SUCCESS) {
981 lim_log(pMac, LOGE,
982 FL
983 ("PMF SA Query timer activation failed!"));
984 goto error;
985 }
986
987 pStaDs->pmfSaQueryState =
988 DPH_SA_QUERY_IN_PROGRESS;
989 goto error;
990
991 /* SA Query procedure still going, respond to Association */
992 /* Request with try again later */
993 case DPH_SA_QUERY_IN_PROGRESS:
994 lim_send_assoc_rsp_mgmt_frame(pMac,
995 eSIR_MAC_TRY_AGAIN_LATER,
996 1, pHdr->sa, subType,
997 0, psessionEntry);
998 goto error;
999
1000 /* SA Query procedure timed out, accept Association Request */
1001 /* normally */
1002 case DPH_SA_QUERY_TIMED_OUT:
1003 pStaDs->pmfSaQueryState =
1004 DPH_SA_QUERY_NOT_IN_PROGRESS;
1005 break;
1006 }
1007 }
1008#endif
1009
1010 /* no change in the capability so drop the frame */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301011 if ((true !=
1012 qdf_mem_cmp(&pStaDs->mlmStaContext.capabilityInfo,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 &pAssocReq->capabilityInfo,
1014 sizeof(tSirMacCapabilityInfo)))
1015 && (subType == LIM_ASSOC)) {
1016 lim_log(pMac, LOGE,
1017 FL(" Received Assoc req in state %X STAid=%d"),
1018 pStaDs->mlmStaContext.mlmState, peerIdx);
1019 goto error;
1020 } else {
1021 /**
1022 * STA sent Re/association Request frame while already in
1023 * 'associated' state. Update STA capabilities and
1024 * send Association response frame with same AID
1025 */
1026 lim_log(pMac, LOG1,
1027 FL("Recved Assoc req from STA already connected"
1028 " UpdateConext"));
1029 pStaDs->mlmStaContext.capabilityInfo =
1030 pAssocReq->capabilityInfo;
1031 if (pStaPreAuthContext
1032 && (pStaPreAuthContext->mlmState ==
1033 eLIM_MLM_AUTHENTICATED_STATE)) {
1034 /* / STA has triggered pre-auth again */
1035 authType = pStaPreAuthContext->authType;
1036 lim_delete_pre_auth_node(pMac, pHdr->sa);
1037 } else
1038 authType = pStaDs->mlmStaContext.authType;
1039
1040 updateContext = true;
1041 if (dph_init_sta_state
1042 (pMac, pHdr->sa, peerIdx, true,
1043 &psessionEntry->dph.dphHashTable)
1044 == NULL) {
1045 lim_log(pMac, LOGE,
1046 FL("could not Init STAid=%d"), peerIdx);
1047 goto error;
1048 }
1049 }
1050 goto sendIndToSme;
1051 } /* end if (lookup for STA in perStaDs fails) */
1052
1053 /* check if sta is allowed per QoS AC rules */
1054 limGetWmeMode(psessionEntry, &wmeMode);
1055 if ((qosMode == eHAL_SET) || (wmeMode == eHAL_SET)) {
1056 /* for a qsta, check if the requested Traffic spec */
1057 /* is admissible */
1058 /* for a non-qsta check if the sta can be admitted */
1059 if (pAssocReq->addtsPresent) {
1060 uint8_t tspecIdx = 0; /* index in the sch tspec table. */
1061 if (lim_admit_control_add_ts
1062 (pMac, pHdr->sa, &(pAssocReq->addtsReq),
1063 &(pAssocReq->qosCapability), 0, false, NULL,
1064 &tspecIdx, psessionEntry) != eSIR_SUCCESS) {
1065 lim_log(pMac, LOGE,
1066 FL("AdmitControl: TSPEC rejected"));
1067 lim_send_assoc_rsp_mgmt_frame(pMac,
1068 eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
1069 1, pHdr->sa, subType,
1070 0, psessionEntry);
1071#ifdef WLAN_DEBUG
1072 pMac->lim.gLimNumAssocReqDropACRejectTS++;
1073#endif
1074 goto error;
1075 }
1076 } else if (lim_admit_control_add_sta(pMac, pHdr->sa, false)
1077 != eSIR_SUCCESS) {
1078 lim_log(pMac, LOGE, FL("AdmitControl: Sta rejected"));
1079 lim_send_assoc_rsp_mgmt_frame(pMac,
1080 eSIR_MAC_QAP_NO_BANDWIDTH_REASON,
1081 1,
1082 pHdr->sa,
1083 subType, 0, psessionEntry);
1084#ifdef WLAN_DEBUG
1085 pMac->lim.gLimNumAssocReqDropACRejectSta++;
1086#endif
1087 goto error;
1088 }
1089 /* else all ok */
1090 lim_log(pMac, LOG1, FL("AdmitControl: Sta OK!"));
1091 }
1092
1093 /**
1094 * STA is Associated !
1095 */
1096 lim_log(pMac, LOGE,
1097 FL("Received %s Req successful from " MAC_ADDRESS_STR),
1098 (LIM_ASSOC == subType) ? "Assoc" : "ReAssoc",
1099 MAC_ADDR_ARRAY(pHdr->sa));
1100
1101 /**
1102 * AID for this association will be same as the peer Index used in DPH table.
1103 * Assign unused/least recently used peer Index from perStaDs.
1104 * NOTE: lim_assign_peer_idx() assigns AID values ranging
1105 * between 1 - cfg_item(WNI_CFG_ASSOC_STA_LIMIT)
1106 */
1107
1108 peerIdx = lim_assign_peer_idx(pMac, psessionEntry);
1109
1110 if (!peerIdx) {
1111 /* Could not assign AID */
1112 /* Reject association */
1113 lim_log(pMac, LOGE,
1114 FL("PeerIdx not avaialble. Reject associaton"));
1115 lim_reject_association(pMac, pHdr->sa,
1116 subType, true, authType,
1117 peerIdx, false,
1118 (tSirResultCodes)
1119 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1120 psessionEntry);
1121
1122 goto error;
1123 }
1124
1125 /**
1126 * Add an entry to hash table maintained by DPH module
1127 */
1128
1129 pStaDs =
1130 dph_add_hash_entry(pMac, pHdr->sa, peerIdx,
1131 &psessionEntry->dph.dphHashTable);
1132
1133 if (pStaDs == NULL) {
1134 /* Could not add hash table entry at DPH */
1135 lim_log(pMac, LOGE,
1136 FL("could not add hash entry at DPH for aid=%d, MacAddr:"
1137 MAC_ADDRESS_STR), peerIdx, MAC_ADDR_ARRAY(pHdr->sa));
1138
1139 /* Release AID */
1140 lim_release_peer_idx(pMac, peerIdx, psessionEntry);
1141
1142 lim_reject_association(pMac, pHdr->sa,
1143 subType, true, authType, peerIdx, false,
1144 (tSirResultCodes)
1145 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1146 psessionEntry);
1147
1148 goto error;
1149 }
1150
1151sendIndToSme:
1152 /*
1153 * check here if the parsedAssocReq already
1154 * pointing to the assoc_req and free it before
1155 * assigning this new pAssocReq
1156 */
1157 if (psessionEntry->parsedAssocReq != NULL) {
1158 pTempAssocReq = psessionEntry->parsedAssocReq[pStaDs->assocId];
1159 if (pTempAssocReq != NULL) {
1160 if (pTempAssocReq->assocReqFrame) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301161 qdf_mem_free(pTempAssocReq->assocReqFrame);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162 pTempAssocReq->assocReqFrame = NULL;
1163 pTempAssocReq->assocReqFrameLength = 0;
1164 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301165 qdf_mem_free(pTempAssocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001166 pTempAssocReq = NULL;
1167 }
1168
1169 psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
1170 assoc_req_copied = true;
1171 }
1172
1173 pStaDs->mlmStaContext.htCapability = pAssocReq->HTCaps.present;
1174#ifdef WLAN_FEATURE_11AC
1175 pStaDs->mlmStaContext.vhtCapability = pAssocReq->VHTCaps.present;
1176#endif
1177 pStaDs->qos.addtsPresent =
1178 (pAssocReq->addtsPresent == 0) ? false : true;
1179 pStaDs->qos.addts = pAssocReq->addtsReq;
1180 pStaDs->qos.capability = pAssocReq->qosCapability;
1181 pStaDs->versionPresent = 0;
1182 /* short slot and short preamble should be updated before doing limaddsta */
1183 pStaDs->shortPreambleEnabled =
1184 (uint8_t) pAssocReq->capabilityInfo.shortPreamble;
1185 pStaDs->shortSlotTimeEnabled =
1186 (uint8_t) pAssocReq->capabilityInfo.shortSlotTime;
1187
1188 pStaDs->valid = 0;
1189 pStaDs->mlmStaContext.authType = authType;
1190 pStaDs->staType = STA_ENTRY_PEER;
1191
1192 /* TODO: If listen interval is more than certain limit, reject the association. */
1193 /* Need to check customer requirements and then implement. */
1194 pStaDs->mlmStaContext.listenInterval = pAssocReq->listenInterval;
1195 pStaDs->mlmStaContext.capabilityInfo = pAssocReq->capabilityInfo;
1196
1197 /* The following count will be used to knock-off the station if it doesn't
1198 * come back to receive the buffered data. The AP will wait for numTimSent number
1199 * of beacons after sending TIM information for the station, before assuming that
1200 * the station is no more associated and disassociates it
1201 */
1202
1203 /** timWaitCount is used by PMM for monitoring the STA's in PS for LINK*/
1204 pStaDs->timWaitCount =
1205 (uint8_t) GET_TIM_WAIT_COUNT(pAssocReq->listenInterval);
1206
1207 /** Initialise the Current successful MPDU's tranfered to this STA count as 0 */
1208 pStaDs->curTxMpduCnt = 0;
1209
1210 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
1211 pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) {
1212 pStaDs->htGreenfield = (uint8_t) pAssocReq->HTCaps.greenField;
1213 pStaDs->htAMpduDensity = pAssocReq->HTCaps.mpduDensity;
1214 pStaDs->htDsssCckRate40MHzSupport =
1215 (uint8_t) pAssocReq->HTCaps.dsssCckMode40MHz;
1216 pStaDs->htLsigTXOPProtection =
1217 (uint8_t) pAssocReq->HTCaps.lsigTXOPProtection;
1218 pStaDs->htMaxAmsduLength =
1219 (uint8_t) pAssocReq->HTCaps.maximalAMSDUsize;
1220 pStaDs->htMaxRxAMpduFactor = pAssocReq->HTCaps.maxRxAMPDUFactor;
1221 pStaDs->htMIMOPSState = pAssocReq->HTCaps.mimoPowerSave;
1222
1223 /* pAssocReq will be copied to psessionEntry->parsedAssocReq
1224 * later
1225 */
1226 ht_cap_ie = ((uint8_t *) &pAssocReq->HTCaps) + 1;
1227
1228 /* check whether AP is enabled with shortGI */
1229 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_20MHZ, &val) !=
1230 eSIR_SUCCESS) {
1231 PELOGE(lim_log(pMac, LOGE,
1232 FL("could not retrieve shortGI 20Mhz CFG"));)
1233 goto error;
1234 }
1235 if (val) {
1236 pStaDs->htShortGI20Mhz =
1237 (uint8_t)pAssocReq->HTCaps.shortGI20MHz;
1238 } else {
1239 /* Unset htShortGI20Mhz in ht_caps*/
1240 *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI20MHZ_S);
1241 pStaDs->htShortGI20Mhz = 0;
1242 }
1243
1244 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_GI_40MHZ, &val) !=
1245 eSIR_SUCCESS) {
1246 PELOGE(lim_log(pMac, LOGE,
1247 FL("could not retrieve shortGI 40Mhz CFG"));)
1248 goto error;
1249 }
1250 if (val) {
1251 pStaDs->htShortGI40Mhz =
1252 (uint8_t)pAssocReq->HTCaps.shortGI40MHz;
1253 } else {
1254 /* Unset htShortGI40Mhz in ht_caps */
1255 *ht_cap_ie &= ~(1 << SIR_MAC_HT_CAP_SHORTGI40MHZ_S);
1256 pStaDs->htShortGI40Mhz = 0;
1257 }
1258
1259 pStaDs->htSupportedChannelWidthSet =
1260 (uint8_t) pAssocReq->HTCaps.supportedChannelWidthSet;
1261 /*
1262 * peer just follows AP; so when we are softAP/GO,
1263 * we just store our session entry's secondary channel offset
1264 * here in peer INFRA STA. However, if peer's 40MHz channel
1265 * width support is disabled then secondary channel will be zero
1266 */
1267 pStaDs->htSecondaryChannelOffset =
1268 (pStaDs->htSupportedChannelWidthSet) ? psessionEntry->
1269 htSecondaryChannelOffset : 0;
1270#ifdef WLAN_FEATURE_11AC
1271 if (pAssocReq->operMode.present) {
1272 pStaDs->vhtSupportedChannelWidthSet =
1273 (uint8_t) ((pAssocReq->operMode.chanWidth ==
1274 eHT_CHANNEL_WIDTH_80MHZ) ?
1275 WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ :
1276 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ);
1277 pStaDs->htSupportedChannelWidthSet =
1278 (uint8_t) (pAssocReq->operMode.
1279 chanWidth ? eHT_CHANNEL_WIDTH_40MHZ :
1280 eHT_CHANNEL_WIDTH_20MHZ);
1281 } else if (pAssocReq->VHTCaps.present) {
1282 /* Check if STA has enabled it's channel bonding mode. */
1283 /* If channel bonding mode is enabled, we decide based on SAP's current configuration. */
1284 /* else, we set it to VHT20. */
1285 pStaDs->vhtSupportedChannelWidthSet =
1286 (uint8_t) ((pStaDs->htSupportedChannelWidthSet ==
1287 eHT_CHANNEL_WIDTH_20MHZ) ?
1288 WNI_CFG_VHT_CHANNEL_WIDTH_20_40MHZ :
1289 psessionEntry->ch_width - 1);
1290 pStaDs->htMaxRxAMpduFactor =
1291 pAssocReq->VHTCaps.maxAMPDULenExp;
1292 }
1293 /* Lesser among the AP and STA bandwidth of operation. */
1294 pStaDs->htSupportedChannelWidthSet =
1295 (pStaDs->htSupportedChannelWidthSet <
1296 psessionEntry->htSupportedChannelWidthSet) ?
1297 pStaDs->htSupportedChannelWidthSet :
1298 psessionEntry->htSupportedChannelWidthSet;
1299
1300#endif
1301 pStaDs->baPolicyFlag = 0xFF;
1302 pStaDs->htLdpcCapable =
1303 (uint8_t) pAssocReq->HTCaps.advCodingCap;
1304 }
1305
1306 if (pAssocReq->VHTCaps.present && pAssocReq->wmeInfoPresent) {
1307 pStaDs->vhtLdpcCapable =
1308 (uint8_t) pAssocReq->VHTCaps.ldpcCodingCap;
1309 }
1310
1311 if (!pAssocReq->wmeInfoPresent) {
1312 pStaDs->mlmStaContext.htCapability = 0;
1313 pStaDs->mlmStaContext.vhtCapability = 0;
1314 }
1315 if (pStaDs->mlmStaContext.vhtCapability) {
1316 if (psessionEntry->txBFIniFeatureEnabled &&
1317 pAssocReq->VHTCaps.suBeamFormerCap)
1318 pStaDs->vhtBeamFormerCapable = 1;
1319 else
1320 pStaDs->vhtBeamFormerCapable = 0;
1321 if (psessionEntry->enable_su_tx_bformer &&
1322 pAssocReq->VHTCaps.suBeamformeeCap)
1323 pStaDs->vht_su_bfee_capable = 1;
1324 else
1325 pStaDs->vht_su_bfee_capable = 0;
1326 }
1327#ifdef WLAN_FEATURE_11AC
1328 if (lim_populate_matching_rate_set(pMac,
1329 pStaDs,
1330 &(pAssocReq->supportedRates),
1331 &(pAssocReq->extendedRates),
1332 pAssocReq->HTCaps.supportedMCSSet,
1333 psessionEntry, &pAssocReq->VHTCaps)
1334 != eSIR_SUCCESS)
1335#else
1336
1337 if (lim_populate_matching_rate_set(pMac,
1338 pStaDs,
1339 &(pAssocReq->supportedRates),
1340 &(pAssocReq->extendedRates),
1341 pAssocReq->HTCaps.supportedMCSSet,
1342 psessionEntry) != eSIR_SUCCESS)
1343#endif
1344 {
1345 /* Could not update hash table entry at DPH with rateset */
1346 lim_log(pMac, LOGE,
1347 FL
1348 ("could not update hash entry at DPH for aid=%d, MacAddr: "
1349 MAC_ADDRESS_STR), peerIdx, MAC_ADDR_ARRAY(pHdr->sa));
1350
1351 /* Release AID */
1352 lim_release_peer_idx(pMac, peerIdx, psessionEntry);
1353
1354 lim_reject_association(pMac, pHdr->sa,
1355 subType, true, authType, peerIdx, true,
1356 (tSirResultCodes)
1357 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1358 psessionEntry);
1359
1360 if (psessionEntry->parsedAssocReq)
1361 pAssocReq =
1362 psessionEntry->parsedAssocReq[pStaDs->assocId];
1363 goto error;
1364 }
1365#ifdef WLAN_FEATURE_11AC
1366 if (pAssocReq->operMode.present) {
1367 pStaDs->vhtSupportedRxNss = pAssocReq->operMode.rxNSS + 1;
1368 } else {
1369 pStaDs->vhtSupportedRxNss =
1370 ((pStaDs->supportedRates.vhtRxMCSMap & MCSMAPMASK2x2)
1371 == MCSMAPMASK2x2) ? 1 : 2;
1372 }
1373#endif
1374
1375 /* / Add STA context at MAC HW (BMU, RHP & TFP) */
1376
1377 pStaDs->qosMode = false;
1378 pStaDs->lleEnabled = false;
1379 if (pAssocReq->capabilityInfo.qos && (qosMode == eHAL_SET)) {
1380 pStaDs->lleEnabled = true;
1381 pStaDs->qosMode = true;
1382 }
1383
1384 pStaDs->wmeEnabled = false;
1385 pStaDs->wsmEnabled = false;
1386 limGetWmeMode(psessionEntry, &wmeMode);
1387 if ((!pStaDs->lleEnabled) && pAssocReq->wmeInfoPresent
1388 && (wmeMode == eHAL_SET)) {
1389 pStaDs->wmeEnabled = true;
1390 pStaDs->qosMode = true;
1391 limGetWsmMode(psessionEntry, &wsmMode);
1392 /* WMM_APSD - WMM_SA related processing should be separate; WMM_SA and WMM_APSD
1393 can coexist */
1394 if (pAssocReq->WMMInfoStation.present) {
1395 /* check whether AP supports or not */
1396 if (LIM_IS_AP_ROLE(psessionEntry) &&
1397 (psessionEntry->apUapsdEnable == 0) &&
1398 (pAssocReq->WMMInfoStation.acbe_uapsd ||
1399 pAssocReq->WMMInfoStation.acbk_uapsd ||
1400 pAssocReq->WMMInfoStation.acvo_uapsd ||
1401 pAssocReq->WMMInfoStation.acvi_uapsd)) {
1402
1403 /**
1404 * Received Re/Association Request from
1405 * STA when UPASD is not supported.
1406 */
1407 lim_log(pMac, LOGE,
1408 FL("AP do not support UAPSD so reply "
1409 "to STA accordingly"));
1410 /* update UAPSD and send it to LIM to add STA */
1411 pStaDs->qos.capability.qosInfo.acbe_uapsd = 0;
1412 pStaDs->qos.capability.qosInfo.acbk_uapsd = 0;
1413 pStaDs->qos.capability.qosInfo.acvo_uapsd = 0;
1414 pStaDs->qos.capability.qosInfo.acvi_uapsd = 0;
1415 pStaDs->qos.capability.qosInfo.maxSpLen = 0;
1416
1417 } else {
1418 /* update UAPSD and send it to LIM to add STA */
1419 pStaDs->qos.capability.qosInfo.acbe_uapsd =
1420 pAssocReq->WMMInfoStation.acbe_uapsd;
1421 pStaDs->qos.capability.qosInfo.acbk_uapsd =
1422 pAssocReq->WMMInfoStation.acbk_uapsd;
1423 pStaDs->qos.capability.qosInfo.acvo_uapsd =
1424 pAssocReq->WMMInfoStation.acvo_uapsd;
1425 pStaDs->qos.capability.qosInfo.acvi_uapsd =
1426 pAssocReq->WMMInfoStation.acvi_uapsd;
1427 pStaDs->qos.capability.qosInfo.maxSpLen =
1428 pAssocReq->WMMInfoStation.max_sp_length;
1429 }
1430 }
1431 if (pAssocReq->wsmCapablePresent && (wsmMode == eHAL_SET))
1432 pStaDs->wsmEnabled = true;
1433
1434 }
1435 /* Re/Assoc Response frame to requesting STA */
1436 pStaDs->mlmStaContext.subType = subType;
1437
1438#ifdef WLAN_FEATURE_11W
1439 pStaDs->rmfEnabled = (pmfConnection) ? 1 : 0;
1440 pStaDs->pmfSaQueryState = DPH_SA_QUERY_NOT_IN_PROGRESS;
1441 timerId.fields.sessionId = psessionEntry->peSessionId;
1442 timerId.fields.peerIdx = peerIdx;
1443 if (wlan_cfg_get_int(pMac, WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL,
1444 &retryInterval) != eSIR_SUCCESS) {
1445 lim_log(pMac, LOGE,
1446 FL
1447 ("Could not retrieve PMF SA Query retry interval value"));
1448 lim_reject_association(pMac, pHdr->sa, subType, true, authType,
1449 peerIdx, false,
1450 (tSirResultCodes)
1451 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1452 psessionEntry);
1453 goto error;
1454 }
1455 if (WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STAMIN > retryInterval) {
1456 retryInterval = WNI_CFG_PMF_SA_QUERY_RETRY_INTERVAL_STADEF;
1457 }
Naveen Rawat22b1a932015-08-26 12:13:18 -07001458 if (tx_timer_create(pMac, &pStaDs->pmfSaQueryTimer, "PMF SA Query timer",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459 lim_pmf_sa_query_timer_handler, timerId.value,
1460 SYS_MS_TO_TICKS((retryInterval * 1024) / 1000),
1461 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
1462 lim_log(pMac, LOGE, FL("could not create PMF SA Query timer"));
1463 lim_reject_association(pMac, pHdr->sa,
1464 subType, true, authType,
1465 peerIdx, false,
1466 (tSirResultCodes)
1467 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1468 psessionEntry);
1469 goto error;
1470 }
1471#endif
1472
1473 if (pAssocReq->ExtCap.present) {
1474 lim_set_stads_rtt_cap(pStaDs,
1475 (struct s_ext_cap *) pAssocReq->ExtCap.bytes, pMac);
1476 } else {
1477 pStaDs->timingMeasCap = 0;
1478 PELOG1(lim_log(pMac, LOG1, FL("ExtCap not present"));)
1479 }
1480
1481 /* BTAMP: Storing the parsed assoc request in the psessionEntry array */
1482 if (psessionEntry->parsedAssocReq)
1483 psessionEntry->parsedAssocReq[pStaDs->assocId] = pAssocReq;
1484 assoc_req_copied = true;
1485
1486 /* BTAMP: If STA context already exist (ie. updateContext = 1)
1487 * for this STA, then we should delete the old one, and add
1488 * the new STA. This is taken care of in the lim_del_sta() routine.
1489 *
1490 * Prior to BTAMP, we were setting this flag so that when
1491 * PE receives SME_ASSOC_CNF, and if this flag is set, then
1492 * PE shall delete the old station and then add. But now in
1493 * BTAMP, we're directly adding station before waiting for
1494 * SME_ASSOC_CNF, so we can do this now.
1495 */
1496 if (!updateContext) {
1497 pStaDs->mlmStaContext.updateContext = 0;
1498
1499 /* BTAMP: Add STA context at HW - issue WMA_ADD_STA_REQ to HAL */
1500 if (lim_add_sta(pMac, pStaDs, false, psessionEntry) !=
1501 eSIR_SUCCESS) {
1502 lim_log(pMac, LOGE,
1503 FL("could not Add STA with assocId=%d"),
1504 pStaDs->assocId);
1505 lim_reject_association(pMac, pStaDs->staAddr,
1506 pStaDs->mlmStaContext.subType,
1507 true,
1508 pStaDs->mlmStaContext.authType,
1509 pStaDs->assocId, true,
1510 (tSirResultCodes)
1511 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1512 psessionEntry);
1513
1514 if (psessionEntry->parsedAssocReq)
1515 pAssocReq = psessionEntry->parsedAssocReq[
1516 pStaDs->assocId];
1517 goto error;
1518 }
1519 } else {
1520 pStaDs->mlmStaContext.updateContext = 1;
1521
1522 mlmPrevState = pStaDs->mlmStaContext.mlmState;
1523
1524 /* As per the HAL/FW needs the reassoc req need not be calling lim_del_sta */
1525 if (subType != LIM_REASSOC) {
1526 /* we need to set the mlmState here in order differentiate in lim_del_sta. */
1527 pStaDs->mlmStaContext.mlmState =
1528 eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE;
1529 if (lim_del_sta(pMac, pStaDs, true, psessionEntry) !=
1530 eSIR_SUCCESS) {
1531 lim_log(pMac, LOGE,
1532 FL
1533 ("could not DEL STA with assocId=%d staId %d"),
1534 pStaDs->assocId, pStaDs->staIndex);
1535 lim_reject_association(pMac, pStaDs->staAddr,
1536 pStaDs->mlmStaContext.
1537 subType, true,
1538 pStaDs->mlmStaContext.
1539 authType, pStaDs->assocId,
1540 true,
1541 (tSirResultCodes)
1542 eSIR_MAC_UNSPEC_FAILURE_STATUS,
1543 psessionEntry);
1544
1545 /* Restoring the state back. */
1546 pStaDs->mlmStaContext.mlmState = mlmPrevState;
1547 if (psessionEntry->parsedAssocReq)
1548 pAssocReq =
1549 psessionEntry->parsedAssocReq[
1550 pStaDs->assocId];
1551 goto error;
1552 }
1553 } else {
1554 /* mlmState is changed in lim_add_sta context */
1555 /* use the same AID, already allocated */
1556 if (lim_add_sta(pMac, pStaDs, false, psessionEntry) !=
1557 eSIR_SUCCESS) {
1558 lim_log(pMac, LOGE,
1559 FL("Could not AddSta with assocId= %d"
1560 "staId %d"),
1561 pStaDs->assocId, pStaDs->staIndex);
1562 lim_reject_association(pMac, pStaDs->staAddr,
1563 pStaDs->mlmStaContext.
1564 subType, true,
1565 pStaDs->mlmStaContext.
1566 authType, pStaDs->assocId,
1567 true,
1568 (tSirResultCodes)
1569 eSIR_MAC_WME_REFUSED_STATUS,
1570 psessionEntry);
1571
1572 /* Restoring the state back. */
1573 pStaDs->mlmStaContext.mlmState = mlmPrevState;
1574 if (psessionEntry->parsedAssocReq)
1575 pAssocReq =
1576 psessionEntry->parsedAssocReq[
1577 pStaDs->assocId];
1578 goto error;
1579 }
1580
1581 }
1582
1583 }
1584
1585 /* AddSta is sucess here */
1586 if (LIM_IS_AP_ROLE(psessionEntry) &&
1587 IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
1588 pAssocReq->HTCaps.present && pAssocReq->wmeInfoPresent) {
1589 /** Update in the HAL Station Table for the Update of the Protection Mode */
1590 lim_post_sm_state_update(pMac, pStaDs->staIndex,
1591 pStaDs->htMIMOPSState,
1592 pStaDs->staAddr,
1593 psessionEntry->smeSessionId);
1594 }
1595
1596 return;
1597
1598error:
1599 if (pAssocReq != NULL) {
1600 if (pAssocReq->assocReqFrame) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301601 qdf_mem_free(pAssocReq->assocReqFrame);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 pAssocReq->assocReqFrame = NULL;
1603 pAssocReq->assocReqFrameLength = 0;
1604 }
1605
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301606 qdf_mem_free(pAssocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 /* to avoid double free */
1608 if (assoc_req_copied && psessionEntry->parsedAssocReq)
1609 psessionEntry->parsedAssocReq[pStaDs->assocId] = NULL;
1610 }
1611
1612 /* If it is not duplicate Assoc request then only make to Null */
1613 if ((pStaDs != NULL) &&
1614 (pStaDs->mlmStaContext.mlmState != eLIM_MLM_WT_ADD_STA_RSP_STATE)) {
1615 if (psessionEntry->parsedAssocReq != NULL) {
1616 pTempAssocReq =
1617 psessionEntry->parsedAssocReq[pStaDs->assocId];
1618 if (pTempAssocReq != NULL) {
1619 if (pTempAssocReq->assocReqFrame) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301620 qdf_mem_free(pTempAssocReq->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001621 assocReqFrame);
1622 pTempAssocReq->assocReqFrame = NULL;
1623 pTempAssocReq->assocReqFrameLength = 0;
1624 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301625 qdf_mem_free(pTempAssocReq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 psessionEntry->
1627 parsedAssocReq[pStaDs->assocId] = NULL;
1628 }
1629 }
1630 }
1631
1632 return;
1633
1634} /*** end lim_process_assoc_req_frame() ***/
1635
1636#ifdef FEATURE_WLAN_WAPI
1637/**
1638 * lim_fill_assoc_ind_wapi_info()- Updates WAPI data in assoc indication
1639 * @mac_ctx: Global Mac context
1640 * @assoc_req: pointer to association request
1641 * @assoc_ind: Pointer to association indication
1642 * @wpsie: WPS IE
1643 *
1644 * This function updates WAPI meta data in association indication message
1645 * sent to SME.
1646 *
1647 * Return: None
1648 */
1649static void lim_fill_assoc_ind_wapi_info(tpAniSirGlobal mac_ctx,
1650 tpSirAssocReq assoc_req, tpLimMlmAssocInd assoc_ind,
1651 uint8_t *wpsie)
1652{
1653 if (assoc_req->wapiPresent && (NULL == wpsie)) {
1654 lim_log(mac_ctx, LOG2,
1655 FL("Received WAPI IE length in Assoc Req is %d"),
1656 assoc_req->wapi.length);
1657 assoc_ind->wapiIE.wapiIEdata[0] = SIR_MAC_WAPI_EID;
1658 assoc_ind->wapiIE.wapiIEdata[1] = assoc_req->wapi.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301659 qdf_mem_copy(&assoc_ind->wapiIE.wapiIEdata[2],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660 assoc_req->wapi.info, assoc_req->wapi.length);
1661 assoc_ind->wapiIE.length =
1662 2 + assoc_req->wapi.length;
1663 }
1664 return;
1665}
1666#endif
1667
1668/**
1669 * lim_fill_assoc_ind_vht_info() - Updates VHT information in assoc indication
1670 * @mac_ctx: Global Mac context
1671 * @assoc_req: pointer to association request
1672 * @session_entry: PE session entry
1673 * @assoc_ind: Pointer to association indication
1674 *
1675 * This function updates VHT information in association indication message
1676 * sent to SME.
1677 *
1678 * Return: None
1679 */
1680static void lim_fill_assoc_ind_vht_info(tpAniSirGlobal mac_ctx,
1681 tpPESession session_entry, tpSirAssocReq assoc_req,
1682 tpLimMlmAssocInd assoc_ind)
1683{
1684 uint8_t chan;
1685
1686 if (session_entry->limRFBand == SIR_BAND_2_4_GHZ) {
1687 if (session_entry->vhtCapability
1688 && assoc_req->VHTCaps.present)
1689 assoc_ind->chan_info.info = MODE_11AC_VHT20;
1690 else if (session_entry->htCapability
1691 && assoc_req->HTCaps.present)
1692 assoc_ind->chan_info.info = MODE_11NG_HT20;
1693 else
1694 assoc_ind->chan_info.info = MODE_11G;
1695 } else {
1696 if (session_entry->vhtCapability
1697 && assoc_req->VHTCaps.present) {
1698 if ((session_entry->ch_width > CH_WIDTH_40MHZ)
1699 && assoc_req->HTCaps.supportedChannelWidthSet) {
1700 chan = session_entry->ch_center_freq_seg0;
1701 assoc_ind->chan_info.band_center_freq1 =
1702 cds_chan_to_freq(chan);
1703 assoc_ind->chan_info.info = MODE_11AC_VHT80;
1704 } else if ((session_entry->ch_width == CH_WIDTH_40MHZ)
1705 && assoc_req->HTCaps.supportedChannelWidthSet) {
1706 assoc_ind->chan_info.info = MODE_11AC_VHT40;
1707 if (session_entry->htSecondaryChannelOffset ==
1708 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
1709 assoc_ind->chan_info.band_center_freq1
1710 += 10;
1711 else
1712 assoc_ind->chan_info.band_center_freq1
1713 -= 10;
1714 } else {
1715 assoc_ind->chan_info.info = MODE_11AC_VHT20;
1716 }
1717 } else if (session_entry->htCapability
1718 && assoc_req->HTCaps.present) {
1719 if ((session_entry->ch_width == CH_WIDTH_40MHZ)
1720 && assoc_req->HTCaps.supportedChannelWidthSet) {
1721 assoc_ind->chan_info.info = MODE_11NA_HT40;
1722 if (session_entry->htSecondaryChannelOffset ==
1723 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
1724 assoc_ind->chan_info.band_center_freq1
1725 += 10;
1726 else
1727 assoc_ind->chan_info.band_center_freq1
1728 -= 10;
1729 } else {
1730 assoc_ind->chan_info.info = MODE_11NA_HT20;
1731 }
1732 } else {
1733 assoc_ind->chan_info.info = MODE_11A;
1734 }
1735 }
1736 return;
1737}
1738
1739/**
1740 * lim_send_mlm_assoc_ind() - Sends assoc indication to SME
1741 * @mac_ctx: Global Mac context
1742 * @sta_ds: Station DPH hash entry
1743 * @session_entry: PE session entry
1744 *
1745 * This function sends either LIM_MLM_ASSOC_IND
1746 * or LIM_MLM_REASSOC_IND to SME.
1747 *
1748 * Return: None
1749 */
1750void lim_send_mlm_assoc_ind(tpAniSirGlobal mac_ctx,
1751 tpDphHashNode sta_ds, tpPESession session_entry)
1752{
1753 tpLimMlmAssocInd assoc_ind = NULL;
1754 tpSirAssocReq assoc_req;
1755 uint16_t temp, rsn_len;
1756 uint32_t phy_mode;
1757 uint8_t sub_type;
1758 uint8_t *wpsie = NULL;
1759 uint32_t tmp;
1760
1761 /* Get a copy of the already parsed Assoc Request */
1762 assoc_req =
1763 (tpSirAssocReq) session_entry->parsedAssocReq[sta_ds->assocId];
1764
1765 /* Get the phy_mode */
1766 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
1767
1768 /* Determine if its Assoc or ReAssoc Request */
1769 if (assoc_req->reassocRequest == 1)
1770 sub_type = LIM_REASSOC;
1771 else
1772 sub_type = LIM_ASSOC;
1773
1774 lim_log(mac_ctx, LOG1,
1775 FL("Sessionid %d ssid %s sub_type %d Associd %d staAddr "
1776 MAC_ADDRESS_STR), session_entry->peSessionId,
1777 assoc_req->ssId.ssId, sub_type, sta_ds->assocId,
1778 MAC_ADDR_ARRAY(sta_ds->staAddr));
1779
1780 if (sub_type == LIM_ASSOC || sub_type == LIM_REASSOC) {
1781 temp = sizeof(tLimMlmAssocInd);
1782
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301783 assoc_ind = qdf_mem_malloc(temp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001784 if (NULL == assoc_ind) {
1785 lim_release_peer_idx(mac_ctx, sta_ds->assocId,
1786 session_entry);
1787 lim_log(mac_ctx, LOGP,
1788 FL("AllocateMemory failed for assoc_ind"));
1789 return;
1790 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301791 qdf_mem_set(assoc_ind, temp, 0);
1792 qdf_mem_copy((uint8_t *) assoc_ind->peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793 (uint8_t *) sta_ds->staAddr, sizeof(tSirMacAddr));
1794 assoc_ind->aid = sta_ds->assocId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301795 qdf_mem_copy((uint8_t *) &assoc_ind->ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 (uint8_t *) &(assoc_req->ssId),
1797 assoc_req->ssId.length + 1);
1798 assoc_ind->sessionId = session_entry->peSessionId;
1799 assoc_ind->authType = sta_ds->mlmStaContext.authType;
1800 assoc_ind->capabilityInfo = assoc_req->capabilityInfo;
1801
1802 /* Fill in RSN IE information */
1803 assoc_ind->rsnIE.length = 0;
1804 /* if WPS IE is present, ignore RSN IE */
1805 if (assoc_req->addIEPresent && assoc_req->addIE.length) {
1806 wpsie = limGetWscIEPtr(mac_ctx,
1807 assoc_req->addIE.addIEdata,
1808 assoc_req->addIE.length);
1809 }
1810 if (assoc_req->rsnPresent && (NULL == wpsie)) {
1811 lim_log(mac_ctx, LOG2, FL("Assoc Req RSN IE len = %d"),
1812 assoc_req->rsn.length);
1813 assoc_ind->rsnIE.length = 2 + assoc_req->rsn.length;
1814 assoc_ind->rsnIE.rsnIEdata[0] = SIR_MAC_RSN_EID;
1815 assoc_ind->rsnIE.rsnIEdata[1] =
1816 assoc_req->rsn.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301817 qdf_mem_copy(&assoc_ind->rsnIE.rsnIEdata[2],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 assoc_req->rsn.info,
1819 assoc_req->rsn.length);
1820 }
1821 /* Fill in 802.11h related info */
1822 if (assoc_req->powerCapabilityPresent
1823 && assoc_req->supportedChannelsPresent) {
1824 assoc_ind->spectrumMgtIndicator = eSIR_TRUE;
1825 assoc_ind->powerCap.minTxPower =
1826 assoc_req->powerCapability.minTxPower;
1827 assoc_ind->powerCap.maxTxPower =
1828 assoc_req->powerCapability.maxTxPower;
1829 lim_convert_supported_channels(mac_ctx, assoc_ind,
1830 assoc_req);
1831 } else {
1832 assoc_ind->spectrumMgtIndicator = eSIR_FALSE;
1833 }
1834
1835 /* This check is to avoid extra Sec IEs present incase of WPS */
1836 if (assoc_req->wpaPresent && (NULL == wpsie)) {
1837 rsn_len = assoc_ind->rsnIE.length;
1838 if ((rsn_len + assoc_req->wpa.length)
1839 >= SIR_MAC_MAX_IE_LENGTH) {
1840 lim_log(mac_ctx, LOGE,
1841 FL("rsnIEdata index out of bounds %d"),
1842 rsn_len);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301843 qdf_mem_free(assoc_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001844 return;
1845 }
1846 assoc_ind->rsnIE.rsnIEdata[rsn_len] =
1847 SIR_MAC_WPA_EID;
1848 assoc_ind->rsnIE.rsnIEdata[rsn_len + 1]
1849 = assoc_req->wpa.length;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301850 qdf_mem_copy(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851 &assoc_ind->rsnIE.rsnIEdata[rsn_len + 2],
1852 assoc_req->wpa.info, assoc_req->wpa.length);
1853 assoc_ind->rsnIE.length += 2 + assoc_req->wpa.length;
1854 }
1855#ifdef FEATURE_WLAN_WAPI
1856 lim_fill_assoc_ind_wapi_info(mac_ctx, assoc_req, assoc_ind,
1857 wpsie);
1858#endif
1859
1860 assoc_ind->addIE.length = 0;
1861 if (assoc_req->addIEPresent) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301862 qdf_mem_copy(&assoc_ind->addIE.addIEdata,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 assoc_req->addIE.addIEdata,
1864 assoc_req->addIE.length);
1865 assoc_ind->addIE.length = assoc_req->addIE.length;
1866 }
1867 /*
1868 * Add HT Capabilities into addIE for OBSS
1869 * processing in hostapd
1870 */
1871 if (assoc_req->HTCaps.present) {
1872 rsn_len = assoc_ind->addIE.length;
1873 if (assoc_ind->addIE.length + DOT11F_IE_HTCAPS_MIN_LEN
1874 + 2 < SIR_MAC_MAX_IE_LENGTH) {
1875 assoc_ind->addIE.addIEdata[rsn_len] =
1876 SIR_MAC_HT_CAPABILITIES_EID;
1877 assoc_ind->addIE.addIEdata[rsn_len + 1] =
1878 DOT11F_IE_HTCAPS_MIN_LEN;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301879 qdf_mem_copy(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001880 &assoc_ind->addIE.addIEdata[rsn_len+2],
1881 ((uint8_t *)&assoc_req->HTCaps) + 1,
1882 DOT11F_IE_HTCAPS_MIN_LEN);
1883 assoc_ind->addIE.length +=
1884 2 + DOT11F_IE_HTCAPS_MIN_LEN;
1885 } else {
1886 lim_log(mac_ctx, LOGP,
1887 FL("Fail:HT capabilities IE to addIE"));
1888 }
1889 }
1890
1891 if (assoc_req->wmeInfoPresent) {
1892 if (wlan_cfg_get_int (mac_ctx,
1893 (uint16_t) WNI_CFG_WME_ENABLED, &tmp)
1894 != eSIR_SUCCESS)
1895 lim_log(mac_ctx, LOGP,
1896 FL("wlan_cfg_get_int failed for id %d"),
1897 WNI_CFG_WME_ENABLED);
1898
1899 /* check whether AP is enabled with WMM */
1900 if (tmp)
1901 assoc_ind->WmmStaInfoPresent = 1;
1902 else
1903 assoc_ind->WmmStaInfoPresent = 0;
1904 /*
1905 * Note: we are not rejecting association here
1906 * because IOT will fail
1907 */
1908 }
1909 /* Required for indicating the frames to upper layer */
1910 assoc_ind->assocReqLength = assoc_req->assocReqFrameLength;
1911 assoc_ind->assocReqPtr = assoc_req->assocReqFrame;
1912
1913 assoc_ind->beaconPtr = session_entry->beacon;
1914 assoc_ind->beaconLength = session_entry->bcnLen;
1915
1916 assoc_ind->chan_info.chan_id =
1917 session_entry->currentOperChannel;
1918 assoc_ind->chan_info.mhz =
1919 cds_chan_to_freq(session_entry->currentOperChannel);
1920 assoc_ind->chan_info.band_center_freq1 =
1921 cds_chan_to_freq(session_entry->currentOperChannel);
1922 assoc_ind->chan_info.band_center_freq2 = 0;
1923 assoc_ind->chan_info.reg_info_1 =
1924 (session_entry->maxTxPower << 16);
1925 assoc_ind->chan_info.reg_info_2 =
1926 (session_entry->maxTxPower << 8);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301927 assoc_ind->chan_info.nss = sta_ds->nss;
1928 assoc_ind->chan_info.rate_flags =
1929 lim_get_max_rate_flags(mac_ctx, sta_ds);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001930 /* updates VHT information in assoc indication */
1931 lim_fill_assoc_ind_vht_info(mac_ctx, session_entry, assoc_req,
1932 assoc_ind);
1933 lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
1934 (uint32_t *) assoc_ind);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301935 qdf_mem_free(assoc_ind);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001936 }
1937 return;
1938}