blob: 43917d0efcb2f5b899ef58859d995a43c900e41c [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002 * Copyright (c) 2011-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_assoc_utils.cc contains the utility functions
30 * LIM uses while processing (Re) Association messages.
31 * Author: Chandra Modumudi
32 * Date: 02/13/02
33 * History:-
34 * Date Modified by Modification Information
35 * --------------------------------------------------------------------
36 * 05/26/10 js WPA handling in (Re)Assoc frames
37 *
38 */
39
40#include "cds_api.h"
41#include "ani_global.h"
42#include "wni_api.h"
43#include "sir_common.h"
44
45#include "wni_cfg.h"
46#include "cfg_api.h"
47
48#include "sch_api.h"
49#include "utils_api.h"
50#include "lim_utils.h"
51#include "lim_assoc_utils.h"
52#include "lim_security_utils.h"
53#include "lim_ser_des_utils.h"
54#include "lim_sta_hash_api.h"
55#include "lim_admit_control.h"
56#include "lim_send_messages.h"
57#include "lim_ibss_peer_mgmt.h"
58#ifdef WLAN_FEATURE_VOWIFI_11R
59#include "lim_ft_defs.h"
60#endif
61#include "lim_session.h"
62
Anurag Chouhan6d760662016-02-20 16:05:43 +053063#include "qdf_types.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064#include "wma_types.h"
65#include "lim_types.h"
66
67/*
68 * fill up the rate info properly based on what is actually supported by the peer
69 * TBD TBD TBD
70 */
71void
72lim_fill_supported_rates_info(tpAniSirGlobal pMac,
73 tpDphHashNode pSta,
74 tpSirSupportedRates pRates, tpPESession psessionEntry)
75{
76 /* pSta will be NULL for self entry, so get the opRateMode based on the self mode. */
77 /* For the peer entry get it from the peer Capabilities present in hash table */
78 if (pSta == NULL)
79 pRates->opRateMode =
80 lim_get_sta_rate_mode((uint8_t) psessionEntry->dot11mode);
81 else
82 pRates->opRateMode =
83 lim_get_sta_peer_type(pMac, pSta, psessionEntry);
84
85}
86
87/**
Srinivas Girigowdacba74732016-01-14 17:35:25 -080088 * lim_cmp_ssid() - utility function to compare SSIDs
89 * @rx_ssid: Received SSID
90 * @session_entry: Session entry
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092 * This function is called in various places within LIM code
Srinivas Girigowdacba74732016-01-14 17:35:25 -080093 * to determine whether received SSID is same as SSID in use.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094 *
Srinivas Girigowdacba74732016-01-14 17:35:25 -080095 * Return: true if SSID matched, false otherwise.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096 */
Srinivas Girigowdacba74732016-01-14 17:35:25 -080097bool lim_cmp_ssid(tSirMacSSid *rx_ssid, tpPESession session_entry)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080098{
Srinivas Girigowdacba74732016-01-14 17:35:25 -080099 return cdf_mem_compare(rx_ssid, &session_entry->ssId,
100 session_entry->ssId.length);
101}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102
103/**
104 * lim_compare_capabilities()
105 *
106 ***FUNCTION:
107 * This function is called during Association/Reassociation
108 * frame handling to determine whether received capabilities
109 * match with local capabilities or not.
110 *
111 ***LOGIC:
112 *
113 ***ASSUMPTIONS:
114 * NA
115 *
116 ***NOTE:
117 * NA
118 *
119 * @param pMac - Pointer to Global MAC structure
120 * @param pAssocReq - Pointer to received Assoc Req frame
121 * @param pLocalCapabs - Pointer to local capabilities
122 *
123 * @return status - true for Capabilitity match else false.
124 */
125
126uint8_t
127lim_compare_capabilities(tpAniSirGlobal pMac,
128 tSirAssocReq *pAssocReq,
129 tSirMacCapabilityInfo *pLocalCapabs,
130 tpPESession psessionEntry)
131{
132 uint32_t val;
133
134 if ((LIM_IS_AP_ROLE(psessionEntry) ||
135 LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
136 (pAssocReq->capabilityInfo.ibss)) {
137 /* Requesting STA asserting IBSS capability. */
138 lim_log(pMac, LOG1,
139 FL("Requesting STA asserting IBSS capability"));
140 return false;
141 }
142 /* Compare CF capabilities */
143 if (pAssocReq->capabilityInfo.cfPollable ||
144 pAssocReq->capabilityInfo.cfPollReq) {
145 /* AP does not support PCF functionality */
146 lim_log(pMac, LOG1,
147 FL(" AP does not support PCF functionality"));
148 return false;
149 }
150 /* Compare short preamble capability */
151 if (pAssocReq->capabilityInfo.shortPreamble &&
152 (pAssocReq->capabilityInfo.shortPreamble !=
153 pLocalCapabs->shortPreamble)) {
154 /* Allowing a STA requesting short preamble while */
155 /* AP does not support it */
156 }
157
158 lim_log(pMac, LOG1, "QoS in AssocReq: %d, local capabs qos: %d",
159 pAssocReq->capabilityInfo.qos, pLocalCapabs->qos);
160
161 /* Compare QoS capability */
162 if (pAssocReq->capabilityInfo.qos &&
163 (pAssocReq->capabilityInfo.qos != pLocalCapabs->qos)) {
164 /*Temporary hack for UPF to skip 11e capability check in order to interop with
165 CSR - proper fix needs to be put in place */
166 lim_log(pMac, LOG1,
167 FL
168 ("Received unmatched QOS but cfg to suppress - continuing"));
169 }
170
171 /*
172 * If AP supports shortSlot and if apple user has
173 * enforced association only from shortSlot station,
174 * then AP must reject any station that does not support
175 * shortSlot
176 */
177 if ((LIM_IS_AP_ROLE(psessionEntry) ||
178 LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) &&
179 (pLocalCapabs->shortSlotTime == 1)) {
180 if (wlan_cfg_get_int
181 (pMac, WNI_CFG_ACCEPT_SHORT_SLOT_ASSOC_ONLY,
182 &val) != eSIR_SUCCESS) {
183 lim_log(pMac, LOGP,
184 FL
185 ("error getting WNI_CFG_FORCE_SHORT_SLOT_ASSOC_ONLY "));
186 return false;
187 }
188 if (val) {
189 if (pAssocReq->capabilityInfo.shortSlotTime !=
190 pLocalCapabs->shortSlotTime) {
191 lim_log(pMac, LOGE,
192 FL
193 ("AP rejects association as station doesnt support shortslot time"));
194 return false;
195 }
196 return false;
197 }
198 }
199
200 return true;
201} /****** end lim_compare_capabilities() ******/
202
203/**
204 * lim_check_rx_basic_rates()
205 *
206 ***FUNCTION:
207 * This function is called during Association/Reassociation
208 * frame handling to determine whether received rates in
209 * Assoc/Reassoc request frames include all BSS basic rates
210 * or not.
211 *
212 ***LOGIC:
213 *
214 ***ASSUMPTIONS:
215 * NA
216 *
217 ***NOTE:
218 * NA
219 *
220 * @param rxRateSet - pointer to SSID structure
221 *
222 * @return status - true if ALL BSS basic rates are present in the
223 * received rateset else false.
224 */
225
226uint8_t
227lim_check_rx_basic_rates(tpAniSirGlobal pMac, tSirMacRateSet rxRateSet,
228 tpPESession psessionEntry)
229{
230 tSirMacRateSet *pRateSet, basicRate;
231 uint8_t i, j, k, match;
232
233 pRateSet = cdf_mem_malloc(sizeof(tSirMacRateSet));
234 if (NULL == pRateSet) {
235 lim_log(pMac, LOGP,
236 FL("call to AllocateMemory failed for RATESET"));
237
238 return false;
239 }
240
241 /* Copy operational rate set from session Entry */
242 cdf_mem_copy(pRateSet->rate, (psessionEntry->rateSet.rate),
243 psessionEntry->rateSet.numRates);
244
245 pRateSet->numRates = psessionEntry->rateSet.numRates;
246
247 /* Extract BSS basic rateset from operational rateset */
248 for (i = 0, j = 0;
249 ((i < pRateSet->numRates) && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
250 if ((pRateSet->rate[i] & 0x80) == 0x80) {
251 /* msb is set, so this is a basic rate */
252 basicRate.rate[j++] = pRateSet->rate[i];
253 }
254 }
255
256 /*
257 * For each BSS basic rate, find if it is present in the
258 * received rateset.
259 */
260 for (k = 0; k < j; k++) {
261 match = 0;
262 for (i = 0;
263 ((i < rxRateSet.numRates)
264 && (i < SIR_MAC_RATESET_EID_MAX)); i++) {
265 if ((rxRateSet.rate[i] | 0x80) == basicRate.rate[k])
266 match = 1;
267 }
268
269 if (!match) {
270 /* Free up memory allocated for rateset */
271 cdf_mem_free((uint8_t *) pRateSet);
272
273 return false;
274 }
275 }
276
277 /* Free up memory allocated for rateset */
278 cdf_mem_free((uint8_t *) pRateSet);
279
280 return true;
281} /****** end lim_check_rx_basic_rates() ******/
282
283/**
284 * lim_check_mcs_set()
285 *
286 ***FUNCTION:
287 * This function is called during Association/Reassociation
288 * frame handling to determine whether received MCS rates in
289 * Assoc/Reassoc request frames includes all Basic MCS Rate Set or not.
290 *
291 ***LOGIC:
292 *
293 ***ASSUMPTIONS:
294 * NA
295 *
296 ***NOTE:
297 * NA
298 *
299 * @param supportedMCSSet - pointer to Supported MCS Rate Set
300 *
301 * @return status - true if ALL MCS Basic Rate Set rates are present in the
302 * received rateset else false.
303 */
304
305uint8_t lim_check_mcs_set(tpAniSirGlobal pMac, uint8_t *supportedMCSSet)
306{
307 uint8_t basicMCSSet[SIZE_OF_BASIC_MCS_SET] = { 0 };
308 uint32_t cfgLen = 0;
309 uint8_t i;
310 uint8_t validBytes;
311 uint8_t lastByteMCSMask = 0x1f;
312
313 cfgLen = WNI_CFG_BASIC_MCS_SET_LEN;
314 if (wlan_cfg_get_str(pMac, WNI_CFG_BASIC_MCS_SET,
315 (uint8_t *) basicMCSSet,
316 (uint32_t *) &cfgLen) != eSIR_SUCCESS) {
317 /* / Could not get Basic MCS rateset from CFG. Log error. */
318 lim_log(pMac, LOGP, FL("could not retrieve Basic MCS rateset"));
319 return false;
320 }
321
322 validBytes = VALID_MCS_SIZE / 8;
323
324 /* check if all the Basic MCS Bits are set in supported MCS bitmap */
325 for (i = 0; i < validBytes; i++) {
326 if ((basicMCSSet[i] & supportedMCSSet[i]) != basicMCSSet[i]) {
327 /* Log is avaiable in calling function in file lim_process_assoc_req_frame.c */
328 lim_log(pMac, LOGW,
329 FL
330 ("One of Basic MCS Set Rates is not supported by the Station."));
331 return false;
332 }
333 }
334
335 /* check the last 5 bits of the valid MCS bitmap */
336 if (((basicMCSSet[i] & lastByteMCSMask) &
337 (supportedMCSSet[i] & lastByteMCSMask)) !=
338 (basicMCSSet[i] & lastByteMCSMask)) {
339 lim_log(pMac, LOGW,
340 FL
341 ("One of Basic MCS Set Rates is not supported by the Station."));
342 return false;
343 }
344
345 return true;
346}
347
348#define SECURITY_SUITE_TYPE_MASK 0xFF
349#define SECURITY_SUITE_TYPE_WEP40 0x1
350#define SECURITY_SUITE_TYPE_TKIP 0x2
351#define SECURITY_SUITE_TYPE_CCMP 0x4
352#define SECURITY_SUITE_TYPE_WEP104 0x4
353
354/**
355 * lim_check_rx_rsn_ie_match()- validate received rsn ie with supported cipher
356 * suites.
357 * @mac_ctx: pointer to global mac structure
358 * @rx_rsn_ie: received rsn IE
359 * @session_entry: pe session entry
360 * @sta_is_ht: peer station HT capability
361 * @pmf_connection: set to true if this is pmf connection
362 *
363 * This function is called during Association/Reassociation
364 * frame handling to determine whether received RSN in
365 * Assoc/Reassoc request frames include supported cipher suites or not.
366 *
367 * Return: eSIR_SUCCESS if ALL BSS basic rates are present in the
368 * received rateset else failure status.
369 */
370
371uint8_t
372lim_check_rx_rsn_ie_match(tpAniSirGlobal mac_ctx, tDot11fIERSN rx_rsn_ie,
373 tpPESession session_entry, uint8_t sta_is_ht,
374 bool *pmf_connection)
375{
376 tDot11fIERSN *rsn_ie;
377 uint8_t i, j, match, only_non_ht_cipher = 1;
378#ifdef WLAN_FEATURE_11W
379 bool we_are_pmf_capable;
380 bool we_require_pmf;
381 bool they_are_pmf_capable;
382 bool they_require_pmf;
383#endif
384
385 /* RSN IE should be received from PE */
386 rsn_ie = &session_entry->gStartBssRSNIe;
387
388 /* Check groupwise cipher suite */
389 for (i = 0; i < sizeof(rx_rsn_ie.gp_cipher_suite); i++)
390 if (rsn_ie->gp_cipher_suite[i] !=
391 rx_rsn_ie.gp_cipher_suite[i]) {
392 lim_log(mac_ctx, LOG3,
393 FL("Invalid groupwise cipher suite"));
394 return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
395 }
396
397 /*
398 * For each Pairwise cipher suite check whether we support
399 * received pairwise
400 */
401 match = 0;
402 for (i = 0; i < rx_rsn_ie.pwise_cipher_suite_count; i++) {
403 for (j = 0; j < rsn_ie->pwise_cipher_suite_count; j++) {
404 if (cdf_mem_compare(&rx_rsn_ie.pwise_cipher_suites[i],
405 &rsn_ie->pwise_cipher_suites[j],
406 sizeof(rsn_ie->pwise_cipher_suites[j]))) {
407 match = 1;
408 break;
409 }
410 }
411
412 if ((sta_is_ht)
413#ifdef ANI_LITTLE_BYTE_ENDIAN
414 &&
415 ((rx_rsn_ie.pwise_cipher_suites[i][3] &
416 SECURITY_SUITE_TYPE_MASK) ==
417 SECURITY_SUITE_TYPE_CCMP))
418#else
419 &&
420 ((rx_rsn_ie.pwise_cipher_suites[i][0] &
421 SECURITY_SUITE_TYPE_MASK) ==
422 SECURITY_SUITE_TYPE_CCMP))
423#endif
424 only_non_ht_cipher = 0;
425
426 }
427
428 if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
429 lim_log(mac_ctx, LOG1, FL("Invalid pairwise cipher suite"));
430 return eSIR_MAC_INVALID_PAIRWISE_CIPHER_STATUS;
431 }
432 /*
433 * Check RSN capabilities
434 * Bit 0 of First Byte - PreAuthentication Capability
435 */
436 if (((rx_rsn_ie.RSN_Cap[0] >> 0) & 0x1) == true) {
437 /* this is supported by AP only */
438 lim_log(mac_ctx, LOG1,
439 FL("Invalid RSN information element capabilities"));
440 return eSIR_MAC_INVALID_RSN_IE_CAPABILITIES_STATUS;
441 }
442
443 *pmf_connection = false;
444
445#ifdef WLAN_FEATURE_11W
446 we_are_pmf_capable = session_entry->pLimStartBssReq->pmfCapable;
447 we_require_pmf = session_entry->pLimStartBssReq->pmfRequired;
448 they_are_pmf_capable = (rx_rsn_ie.RSN_Cap[0] >> 7) & 0x1;
449 they_require_pmf = (rx_rsn_ie.RSN_Cap[0] >> 6) & 0x1;
450
451 if ((they_require_pmf && they_are_pmf_capable && !we_are_pmf_capable) ||
452 (we_require_pmf && !they_are_pmf_capable)) {
453 lim_log(mac_ctx, LOG1,
454 FL("Association fail, robust management frames policy"
455 " violation they_require_pmf =%d"
456 " theyArePMFCapable %d weArePMFCapable %d"
457 " weRequirePMF %d theyArePMFCapable %d"),
458 they_require_pmf, they_are_pmf_capable,
459 we_are_pmf_capable, we_require_pmf,
460 they_are_pmf_capable);
461 return eSIR_MAC_ROBUST_MGMT_FRAMES_POLICY_VIOLATION;
462 }
463
464 if (they_are_pmf_capable && we_are_pmf_capable)
465 *pmf_connection = true;
466
467 lim_log(mac_ctx, LOG1,
468 FL("weAreCapable %d, weRequire %d, theyAreCapable %d,"
469 " theyRequire %d, PMFconnection %d"),
470 we_are_pmf_capable, we_require_pmf, they_are_pmf_capable,
471 they_require_pmf, *pmf_connection);
472#endif
473
474 return eSIR_SUCCESS;
475}
476
477/**
478 * lim_check_rx_wpa_ie_match() - to check supported cipher suites
479 *
480 * @mac: pointer to global mac structure
481 * @rx_wpaie: Received WPA IE in (Re)Assco req
482 * @session_entry: pointer to PE session
483 * @sta_is_ht: peer station is HT
484 *
485 * This function is called during Association/Reassociation
486 * frame handling to determine whether received RSN in
487 * Assoc/Reassoc request frames include supported cipher suites or not.
488 *
489 * Return: Success if ALL BSS basic rates are present in the
490 * received rateset else failure status.
491 */
492
493uint8_t
494lim_check_rx_wpa_ie_match(tpAniSirGlobal mac, tDot11fIEWPA rx_wpaie,
495 tpPESession session_entry, uint8_t sta_is_ht)
496{
497 tDot11fIEWPA *wpa_ie;
498 uint8_t i, j, match, only_non_ht_cipher = 1;
499
500 /* WPA IE should be received from PE */
501 wpa_ie = &session_entry->gStartBssWPAIe;
502
503 /* Check groupwise cipher suite */
504 for (i = 0; i < 4; i++) {
505 if (wpa_ie->multicast_cipher[i] != rx_wpaie.multicast_cipher[i]) {
506 lim_log(mac, LOG1,
507 FL("Invalid groupwise cipher suite"));
508 return eSIR_MAC_INVALID_GROUP_CIPHER_STATUS;
509 }
510 }
511
512 /*
513 * For each Pairwise cipher suite check whether we support
514 * received pairwise
515 */
516 match = 0;
517 for (i = 0; i < rx_wpaie.unicast_cipher_count; i++) {
518 for (j = 0; j < wpa_ie->unicast_cipher_count; j++) {
519 if (cdf_mem_compare(rx_wpaie.unicast_ciphers[i],
520 wpa_ie->unicast_ciphers[j], 4)) {
521 match = 1;
522 break;
523 }
524 }
525
526 if ((sta_is_ht)
527#ifdef ANI_LITTLE_BYTE_ENDIAN
528 &&
529 ((rx_wpaie.
530 unicast_ciphers[i][3] & SECURITY_SUITE_TYPE_MASK) ==
531 SECURITY_SUITE_TYPE_CCMP))
532#else
533 &&
534 ((rx_wpaie.
535 unicast_ciphers[i][0] & SECURITY_SUITE_TYPE_MASK) ==
536 SECURITY_SUITE_TYPE_CCMP))
537#endif
538 {
539 only_non_ht_cipher = 0;
540 }
541
542 }
543
544 if ((!match) || ((sta_is_ht) && only_non_ht_cipher)) {
545 lim_log(mac, LOG1, FL("Invalid pairwise cipher suite"));
546 return eSIR_MAC_CIPHER_SUITE_REJECTED_STATUS;
547 }
548
549 return eSIR_SUCCESS;
550}
551
552/**
553 * lim_cleanup_rx_path()
554 *
555 ***FUNCTION:
556 * This function is called to cleanup STA state at SP & RFP.
557 *
558 ***LOGIC:
559 * To circumvent RFP's handling of dummy packet when it does not
560 * have an incomplete packet for the STA to be deleted, a packet
561 * with 'more framgents' bit set will be queued to RFP's WQ before
562 * queuing 'dummy packet'.
563 * A 'dummy' BD is pushed into RFP's WQ with type=00, subtype=1010
564 * (Disassociation frame) and routing flags in BD set to eCPU's
565 * Low Priority WQ.
566 * RFP cleans up its local context for the STA id mentioned in the
567 * BD and then pushes BD to eCPU's low priority WQ.
568 *
569 ***ASSUMPTIONS:
570 * NA
571 *
572 ***NOTE:
573 * NA
574 *
575 * @param pMac Pointer to Global MAC structure
576 * @param pStaDs Pointer to the per STA data structure
577 * initialized by LIM and maintained at DPH
578 *
579 * @return None
580 */
581
582tSirRetStatus
583lim_cleanup_rx_path(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
584 tpPESession psessionEntry)
585{
586 tSirRetStatus retCode = eSIR_SUCCESS;
587
588 lim_log(pMac, LOG1, FL("Cleanup Rx Path for AID : %d"
589 "psessionEntry->limSmeState : %d, mlmState : %d"),
590 pStaDs->assocId, psessionEntry->limSmeState,
591 pStaDs->mlmStaContext.mlmState);
592
593 psessionEntry->isCiscoVendorAP = false;
594
595 if (pMac->lim.gLimAddtsSent) {
596 MTRACE(mac_trace
597 (pMac, TRACE_CODE_TIMER_DEACTIVATE,
598 psessionEntry->peSessionId, eLIM_ADDTS_RSP_TIMER));
599 tx_timer_deactivate(&pMac->lim.limTimers.gLimAddtsRspTimer);
600 }
601
602 if (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_ASSOC_CNF_STATE) {
603 lim_deactivate_and_change_per_sta_id_timer(pMac, eLIM_CNF_WAIT_TIMER,
604 pStaDs->assocId);
605
606 if (!pStaDs->mlmStaContext.updateContext) {
607 /**
608 * There is no context at Polaris to delete.
609 * Release our assigned AID back to the free pool
610 */
611 if (LIM_IS_AP_ROLE(psessionEntry) ||
612 LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
613 lim_release_peer_idx(pMac, pStaDs->assocId,
614 psessionEntry);
615 }
616 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
617 pStaDs->assocId, psessionEntry);
618
619 return retCode;
620 }
621 }
622 /* delete all tspecs associated with this sta. */
623 lim_admit_control_delete_sta(pMac, pStaDs->assocId);
624
625 /**
626 * Make STA hash entry invalid at eCPU so that DPH
627 * does not process any more data packets and
628 * releases those BDs
629 */
630 pStaDs->valid = 0;
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800631 lim_send_sme_tsm_ie_ind(pMac, psessionEntry, 0, 0, 0);
632 /* Any roaming related changes should be above this line */
633 if (psessionEntry->bRoamSynchInProgress)
634 return eSIR_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
636
637 if (LIM_IS_STA_ROLE(psessionEntry) ||
638 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
639 MTRACE(mac_trace
640 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
641 eLIM_MLM_WT_DEL_STA_RSP_STATE));
642 psessionEntry->limMlmState = eLIM_MLM_WT_DEL_STA_RSP_STATE;
643 /* Deactivating probe after heart beat timer */
644 lim_deactivate_and_change_timer(pMac, eLIM_PROBE_AFTER_HB_TIMER);
645 lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
646 pMac->lim.gLastBeaconDtimCount = 0;
647 pMac->lim.gLastBeaconDtimPeriod = 0;
648
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800649
650 }
651#ifdef WLAN_DEBUG
652 /* increment a debug count */
653 pMac->lim.gLimNumRxCleanup++;
654#endif
Abhishek Singh96bda8e2015-12-03 16:45:35 +0530655 /* Do DEL BSS or DEL STA only if ADD BSS was success */
656 if (!psessionEntry->add_bss_failed) {
657 if (psessionEntry->limSmeState == eLIM_SME_JOIN_FAILURE_STATE) {
658 retCode =
659 lim_del_bss(pMac, pStaDs, psessionEntry->bssIdx,
660 psessionEntry);
661 } else
662 retCode = lim_del_sta(pMac,
663 pStaDs, true, psessionEntry);
664 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665
666 return retCode;
667
668} /*** end lim_cleanup_rx_path() ***/
669
670/**
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -0800671 * lim_send_del_sta_cnf() - Send Del sta confirmation
672 * @pMac: Pointer to Global MAC structure
673 * @sta_dsaddr: sta ds address
674 * @staDsAssocId: sta ds association id
675 * @mlmStaContext: MLM station context
676 * @statusCode: Status code
677 * @psessionEntry: Session entry
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800678 *
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -0800679 * This function is called to send appropriate CNF message to SME.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800680 *
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -0800681 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800683void
Anurag Chouhan6d760662016-02-20 16:05:43 +0530684lim_send_del_sta_cnf(tpAniSirGlobal pMac, struct qdf_mac_addr sta_dsaddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800685 uint16_t staDsAssocId, tLimMlmStaContext mlmStaContext,
686 tSirResultCodes statusCode, tpPESession psessionEntry)
687{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688 tLimMlmDisassocCnf mlmDisassocCnf;
689 tLimMlmDeauthCnf mlmDeauthCnf;
690 tLimMlmPurgeStaInd mlmPurgeStaInd;
691
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -0800692 lim_log(pMac, LOG1,
693 FL("Sessionid: %d staDsAssocId: %d Trigger: %d statusCode: %d sta_dsaddr: "MAC_ADDRESS_STR),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800694 psessionEntry->peSessionId, staDsAssocId,
695 mlmStaContext.cleanupTrigger, statusCode,
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -0800696 MAC_ADDR_ARRAY(sta_dsaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697
698 if (LIM_IS_STA_ROLE(psessionEntry) ||
699 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
700 /* Set BSSID at CFG to null */
701 tSirMacAddr nullAddr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
702
703 sir_copy_mac_addr(nullAddr, psessionEntry->bssId);
704
705 /* Free up buffer allocated for JoinReq held by */
706 /* MLM state machine */
707 if (psessionEntry->pLimMlmJoinReq) {
708 cdf_mem_free(psessionEntry->pLimMlmJoinReq);
709 psessionEntry->pLimMlmJoinReq = NULL;
710 }
711
712 psessionEntry->limAID = 0;
713
Edhar, Mahesh Kumare3c8d352015-11-16 12:03:45 +0530714 } else if (
715 (mlmStaContext.cleanupTrigger ==
716 eLIM_LINK_MONITORING_DISASSOC) ||
717 (mlmStaContext.cleanupTrigger ==
718 eLIM_LINK_MONITORING_DEAUTH)) {
719 /* only for non-STA cases PE/SME is serialized */
720 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800721 }
722
723 if ((mlmStaContext.cleanupTrigger ==
Edhar, Mahesh Kumare3c8d352015-11-16 12:03:45 +0530724 eLIM_HOST_DISASSOC) ||
725 (mlmStaContext.cleanupTrigger ==
726 eLIM_LINK_MONITORING_DISASSOC) ||
727 (mlmStaContext.cleanupTrigger ==
728 eLIM_PROMISCUOUS_MODE_DISASSOC)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800729 /**
730 * Host or LMM driven Disassociation.
731 * Issue Disassoc Confirm to SME.
732 */
733 lim_log(pMac, LOGW,
734 FL("Lim Posting DISASSOC_CNF to Sme. Trigger: %d"),
735 mlmStaContext.cleanupTrigger);
736
737 cdf_mem_copy((uint8_t *) &mlmDisassocCnf.peerMacAddr,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530738 (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800739 mlmDisassocCnf.resultCode = statusCode;
740 mlmDisassocCnf.disassocTrigger = mlmStaContext.cleanupTrigger;
741 /* Update PE session Id */
742 mlmDisassocCnf.sessionId = psessionEntry->peSessionId;
743
744 lim_post_sme_message(pMac,
745 LIM_MLM_DISASSOC_CNF,
746 (uint32_t *) &mlmDisassocCnf);
747 } else if ((mlmStaContext.cleanupTrigger ==
Edhar, Mahesh Kumare3c8d352015-11-16 12:03:45 +0530748 eLIM_HOST_DEAUTH) ||
749 (mlmStaContext.cleanupTrigger ==
750 eLIM_LINK_MONITORING_DEAUTH)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800751 /**
752 * Host or LMM driven Deauthentication.
753 * Issue Deauth Confirm to SME.
754 */
755 lim_log(pMac, LOGW,
756 FL("Lim Posting DEAUTH_CNF to Sme. Trigger: %d"),
757 mlmStaContext.cleanupTrigger);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530758 qdf_copy_macaddr(&mlmDeauthCnf.peer_macaddr, &sta_dsaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 mlmDeauthCnf.resultCode = statusCode;
760 mlmDeauthCnf.deauthTrigger = mlmStaContext.cleanupTrigger;
761 /* PE session Id */
762 mlmDeauthCnf.sessionId = psessionEntry->peSessionId;
763
764 lim_post_sme_message(pMac,
765 LIM_MLM_DEAUTH_CNF,
766 (uint32_t *) &mlmDeauthCnf);
767 } else if ((mlmStaContext.cleanupTrigger ==
768 eLIM_PEER_ENTITY_DISASSOC) ||
769 (mlmStaContext.cleanupTrigger == eLIM_PEER_ENTITY_DEAUTH)) {
770 /**
771 * Received Disassociation/Deauthentication from peer.
772 * Issue Purge Ind to SME.
773 */
774 lim_log(pMac, LOGW,
775 FL("Lim Posting PURGE_STA_IND to Sme. Trigger: %d"),
776 mlmStaContext.cleanupTrigger);
777 cdf_mem_copy((uint8_t *) &mlmPurgeStaInd.peerMacAddr,
Anurag Chouhan6d760662016-02-20 16:05:43 +0530778 (uint8_t *) sta_dsaddr.bytes, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800779 mlmPurgeStaInd.reasonCode =
780 (uint8_t) mlmStaContext.disassocReason;
781 mlmPurgeStaInd.aid = staDsAssocId;
782 mlmPurgeStaInd.purgeTrigger = mlmStaContext.cleanupTrigger;
783 mlmPurgeStaInd.sessionId = psessionEntry->peSessionId;
784
785 lim_post_sme_message(pMac,
786 LIM_MLM_PURGE_STA_IND,
787 (uint32_t *) &mlmPurgeStaInd);
788 } else if (mlmStaContext.cleanupTrigger == eLIM_JOIN_FAILURE) {
789 /* PE setup the peer entry in HW upfront, right after join is completed. */
790 /* If there is a failure during rest of the assoc sequence, this context needs to be cleaned up. */
791 uint8_t smesessionId;
792 uint16_t smetransactionId;
793
794 smesessionId = psessionEntry->smeSessionId;
795 smetransactionId = psessionEntry->transactionId;
796
797 psessionEntry->limSmeState = eLIM_SME_JOIN_FAILURE_STATE;
798 MTRACE(mac_trace
799 (pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
800 psessionEntry->limSmeState));
801
802 /* if it is a reassoc failure to join new AP */
803 if ((mlmStaContext.resultCode ==
804 eSIR_SME_FT_REASSOC_TIMEOUT_FAILURE)
805 || (mlmStaContext.resultCode == eSIR_SME_FT_REASSOC_FAILURE)
806 || (mlmStaContext.resultCode ==
807 eSIR_SME_REASSOC_TIMEOUT_RESULT_CODE)) {
808 lim_log(pMac, LOG1,
809 FL("Lim Posting eWNI_SME_REASSOC_RSP to SME"
810 "resultCode: %d, statusCode: %d,"
811 "sessionId: %d"),
812 mlmStaContext.resultCode,
813 mlmStaContext.protStatusCode,
814 psessionEntry->peSessionId);
815
816 if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
817 pe_delete_session(pMac, psessionEntry);
818 psessionEntry = NULL;
819 }
820
821 lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_REASSOC_RSP,
822 mlmStaContext.resultCode,
823 mlmStaContext.protStatusCode,
824 psessionEntry, smesessionId,
825 smetransactionId);
826 } else {
827 cdf_mem_free(psessionEntry->pLimJoinReq);
828 psessionEntry->pLimJoinReq = NULL;
829
830 lim_log(pMac, LOG1,
831 FL("Lim Posting eWNI_SME_JOIN_RSP to SME."
832 "resultCode: %d,statusCode: %d,"
833 "sessionId: %d"),
834 mlmStaContext.resultCode,
835 mlmStaContext.protStatusCode,
836 psessionEntry->peSessionId);
837
838 if (mlmStaContext.resultCode != eSIR_SME_SUCCESS) {
839 pe_delete_session(pMac, psessionEntry);
840 psessionEntry = NULL;
841 }
842
843 lim_send_sme_join_reassoc_rsp(pMac, eWNI_SME_JOIN_RSP,
844 mlmStaContext.resultCode,
845 mlmStaContext.protStatusCode,
846 psessionEntry, smesessionId,
847 smetransactionId);
848 }
849
850 }
851
852 if (NULL != psessionEntry && !LIM_IS_AP_ROLE(psessionEntry)) {
853 pe_delete_session(pMac, psessionEntry);
854 psessionEntry = NULL;
855 }
856}
857
858/**
859 * lim_reject_association() - function to reject Re/Association Request
860 *
861 * @mac_ctx: pointer to global mac structure
862 * @peer_addr: mac address of the peer
863 * @sub_type: Indicates whether it is Association Request (=0) or
864 * Reassociation Request (=1) frame
865 * @add_pre_auth_context:Indicates whether pre-auth context
866 * to be added for this STA
867 * @auth_type: Indicates auth type to be added
868 * @sta_id: Indicates staId of the STA being rejected
869 * association
870 * @delete_sta: Indicates whether to delete STA context
871 * at Polaris
872 * @result_code: Indicates what reasonCode to be sent in
873 * Re/Assoc response to STA
874 * @session_entry: pointer to PE session
875 *
876 * This function is called whenever Re/Association Request need
877 * to be rejected due to failure in assigning an AID or failure
878 * in adding STA context at Polaris or reject by applications.
879 * Resources allocated if any are freedup and (Re) Association
880 * Response frame is sent to requesting STA. Pre-Auth context
881 * will be added for this STA if it does not exist already
882 *
883 * Return: none
884 */
885
886void
887lim_reject_association(tpAniSirGlobal mac_ctx, tSirMacAddr peer_addr,
888 uint8_t sub_type, uint8_t add_pre_auth_context,
889 tAniAuthType auth_type, uint16_t sta_id,
890 uint8_t delete_sta, tSirResultCodes result_code,
891 tpPESession session_entry)
892{
893 tpDphHashNode sta_ds;
894
895 lim_log(mac_ctx, LOG1,
896 FL("Sessionid: %d auth_type: %d sub_type: %d add_pre_auth_context: %d sta_id: %d delete_sta: %d result_code : %d peer_addr: " MAC_ADDRESS_STR),
897 session_entry->peSessionId, auth_type, sub_type,
898 add_pre_auth_context, sta_id, delete_sta, result_code,
899 MAC_ADDR_ARRAY(peer_addr));
900
901 if (add_pre_auth_context) {
902 /* Create entry for this STA in pre-auth list */
903 struct tLimPreAuthNode *auth_node;
904
905 auth_node = lim_acquire_free_pre_auth_node(mac_ctx,
906 &mac_ctx->lim.gLimPreAuthTimerTable);
907
908 if (auth_node) {
909 cdf_mem_copy((uint8_t *) auth_node->peerMacAddr,
910 peer_addr, sizeof(tSirMacAddr));
911 auth_node->fTimerStarted = 0;
912 auth_node->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
913 auth_node->authType = (tAniAuthType) auth_type;
Anurag Chouhan210db072016-02-22 18:42:15 +0530914 auth_node->timestamp = qdf_mc_timer_get_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915 lim_add_pre_auth_node(mac_ctx, auth_node);
916 }
917 }
918
919 if (delete_sta == false) {
920 lim_send_assoc_rsp_mgmt_frame(mac_ctx,
921 eSIR_MAC_MAX_ASSOC_STA_REACHED_STATUS,
922 1, peer_addr, sub_type, 0, session_entry);
923 /* Log error */
924 lim_log(mac_ctx, LOGW,
925 FL("received Re/Assoc req when max associated STAs reached from "));
926 lim_print_mac_addr(mac_ctx, peer_addr, LOGW);
927 lim_send_sme_max_assoc_exceeded_ntf(mac_ctx, peer_addr,
928 session_entry->smeSessionId);
929 return;
930 }
931
932 sta_ds = dph_get_hash_entry(mac_ctx, sta_id,
933 &session_entry->dph.dphHashTable);
934
935 if (sta_ds == NULL) {
936 lim_log(mac_ctx, LOGW,
937 FL("No STA context, yet rejecting Association"));
938 return;
939 }
940
941 /*
942 * Polaris has state for this STA.
943 * Trigger cleanup.
944 */
945 sta_ds->mlmStaContext.cleanupTrigger = eLIM_REASSOC_REJECT;
946
947 /* Receive path cleanup */
948 lim_cleanup_rx_path(mac_ctx, sta_ds, session_entry);
949
950 /*
951 * Send Re/Association Response with
952 * status code to requesting STA.
953 */
954 lim_send_assoc_rsp_mgmt_frame(mac_ctx, result_code, 0, peer_addr,
955 sub_type, 0, session_entry);
956
957 if (session_entry->parsedAssocReq[sta_ds->assocId] != NULL) {
958 uint8_t *assoc_req_frame;
959
960 assoc_req_frame = (uint8_t *)((tpSirAssocReq) (session_entry->
961 parsedAssocReq[sta_ds->assocId]))->assocReqFrame;
962 /*
963 *Assoction confirmation is complete,
964 *free the copy of association request frame.
965 */
966 if (assoc_req_frame) {
967 cdf_mem_free(assoc_req_frame);
968 assoc_req_frame = NULL;
969 }
970
971 cdf_mem_free(session_entry->parsedAssocReq[sta_ds->assocId]);
972 session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
973 }
974}
975
976/**
977 * lim_decide_ap_protection_on_ht20_delete() - function to update protection
978 * parameters.
979 * @mac_ctx: pointer to global mac structure
980 * @sta_ds: station node
981 * @beacon_params: ap beacon parameters
982 * @session_entry: pe session entry
983 *
984 * protection related function while HT20 station is getting deleted.
985 *
986 * Return: none
987 */
988static void
989lim_decide_ap_protection_on_ht20_delete(tpAniSirGlobal mac_ctx,
990 tpDphHashNode sta_ds,
991 tpUpdateBeaconParams beacon_params,
992 tpPESession session_entry)
993{
994 uint32_t i = 0;
995
996 lim_log(mac_ctx, LOG1,
997 FL("(%d) A HT 20 STA is disassociated. Addr is %pM"),
998 session_entry->gLimHt20Params.numSta, sta_ds->staAddr);
999
1000 if (session_entry->gLimHt20Params.numSta > 0) {
1001 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1002 if (!session_entry->protStaCache[i].active)
1003 continue;
1004
1005 if (cdf_mem_compare(session_entry->protStaCache[i].addr,
1006 sta_ds->staAddr, sizeof(tSirMacAddr))) {
1007 session_entry->gLimHt20Params.numSta--;
1008 session_entry->protStaCache[i].active =
1009 false;
1010 break;
1011 }
1012 }
1013 }
1014
1015 if (session_entry->gLimHt20Params.numSta == 0) {
1016 /* disable protection */
1017 lim_log(mac_ctx, LOG1, FL("No 11B STA exists, PESessionID %d"),
1018 session_entry->peSessionId);
1019 lim_enable_ht20_protection(mac_ctx, false, false, beacon_params,
1020 session_entry);
1021 }
1022}
1023
1024/**
1025 * lim_decide_ap_protection_on_delete() - update SAP protection on station
1026 * deletion.
1027 * @mac_ctx: pointer to global mac structure
1028 * @sta_ds: station node
1029 * @beacon_params: ap beacon parameters
1030 * @session_entry: pe session entry
1031 *
1032 * Decides about protection related settings when a station is getting deleted.
1033 *
1034 * Return: none
1035 */
1036void
1037lim_decide_ap_protection_on_delete(tpAniSirGlobal mac_ctx,
1038 tpDphHashNode sta_ds,
1039 tpUpdateBeaconParams beacon_params,
1040 tpPESession session_entry)
1041{
1042 uint32_t phy_mode;
1043 tHalBitVal erp_enabled = eHAL_CLEAR;
1044 tSirRFBand rf_band = SIR_BAND_UNKNOWN;
1045 uint32_t i;
1046
1047 if (NULL == sta_ds)
1048 return;
1049
1050 lim_get_rf_band_new(mac_ctx, &rf_band, session_entry);
1051 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
1052 erp_enabled = sta_ds->erpEnabled;
1053
1054 if ((SIR_BAND_5_GHZ == rf_band) &&
1055 (true == session_entry->htCapability) &&
1056 (session_entry->beaconParams.llaCoexist) &&
1057 (false == sta_ds->mlmStaContext.htCapability)) {
1058 /*
1059 * we are HT. if we are 11A, then protection is not required or
1060 * we are HT and 11A station is leaving.
1061 * protection consideration required.
1062 * HT station leaving ==> this case is commonly handled
1063 * between both the bands below.
1064 */
1065 lim_log(mac_ctx, LOG1,
1066 FL("(%d) A 11A STA is disassociated. Addr is %pM"),
1067 session_entry->gLim11aParams.numSta, sta_ds->staAddr);
1068 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1069 if (session_entry->protStaCache[i].active &&
1070 cdf_mem_compare(
1071 session_entry->protStaCache[i].addr,
1072 sta_ds->staAddr,
1073 sizeof(tSirMacAddr))) {
1074 session_entry->protStaCache[i].active = false;
1075 break;
1076 }
1077 }
1078
1079 if (session_entry->gLim11aParams.numSta == 0) {
1080 /* disable protection */
1081 lim_update_11a_protection(mac_ctx, false, false,
1082 beacon_params, session_entry);
1083 }
1084 }
1085
1086 /* we are HT or 11G and 11B station is getting deleted */
1087 if ((SIR_BAND_2_4_GHZ == rf_band) &&
1088 (phy_mode == WNI_CFG_PHY_MODE_11G ||
1089 session_entry->htCapability) &&
1090 (erp_enabled == eHAL_CLEAR)) {
1091 lim_log(mac_ctx, LOG1,
1092 FL("(%d) A legacy STA is disassociated. Addr is %pM"),
1093 session_entry->gLim11bParams.numSta, sta_ds->staAddr);
1094 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1095 if (session_entry->protStaCache[i].active &&
1096 cdf_mem_compare(
1097 session_entry->protStaCache[i].addr,
1098 sta_ds->staAddr,
1099 sizeof(tSirMacAddr))) {
1100 session_entry->gLim11bParams.numSta--;
1101 session_entry->protStaCache[i].active =
1102 false;
1103 break;
1104 }
1105 }
1106
1107 if (session_entry->gLim11bParams.numSta == 0) {
1108 /* disable protection */
1109 lim_enable11g_protection(mac_ctx, false, false,
1110 beacon_params, session_entry);
1111 }
1112 }
1113
1114 /*
1115 * we are HT AP and non-11B station is leaving.
1116 * 11g station is leaving
1117 */
1118 if ((SIR_BAND_2_4_GHZ == rf_band) &&
1119 session_entry->htCapability &&
1120 !sta_ds->mlmStaContext.htCapability) {
1121 lim_log(mac_ctx, LOG1,
1122 FL("(%d) A 11g STA is disassociated. Addr is %pM"),
1123 session_entry->gLim11bParams.numSta, sta_ds->staAddr);
1124 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1125 if (session_entry->protStaCache[i].active &&
1126 cdf_mem_compare(
1127 session_entry->protStaCache[i].addr,
1128 sta_ds->staAddr,
1129 sizeof(tSirMacAddr))) {
1130 session_entry->gLim11gParams.numSta--;
1131 session_entry->protStaCache[i].active = false;
1132 break;
1133 }
1134 }
1135
1136 if (session_entry->gLim11gParams.numSta == 0) {
1137 /* disable protection */
1138 lim_enable_ht_protection_from11g(mac_ctx, false, false,
1139 beacon_params,
1140 session_entry);
1141 }
1142 }
1143
1144 if (!((true == session_entry->htCapability) &&
1145 (true == sta_ds->mlmStaContext.htCapability)))
1146 return;
1147
1148 /*
1149 * Applies to 2.4 as well as 5 GHZ.
1150 * HT non-GF leaving
1151 */
1152 if (!sta_ds->htGreenfield) {
1153 lim_log(mac_ctx, LOG1,
1154 FL("(%d) A non-GF STA is disassociated. Addr is %pM"),
1155 session_entry->gLimNonGfParams.numSta, sta_ds->staAddr);
1156 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1157 if (session_entry->protStaCache[i].active &&
1158 cdf_mem_compare(
1159 session_entry->protStaCache[i].addr,
1160 sta_ds->staAddr,
1161 sizeof(tSirMacAddr))) {
1162 session_entry->protStaCache[i].active = false;
1163 break;
1164 }
1165 }
1166
1167 if (session_entry->gLimNonGfParams.numSta == 0) {
1168 /* disable protection */
1169 lim_enable_ht_non_gf_protection(mac_ctx, false, false,
1170 beacon_params, session_entry);
1171 }
1172 }
1173
1174 /*
1175 * Applies to 2.4 as well as 5 GHZ.
1176 * HT 20Mhz station leaving
1177 */
1178 if (session_entry->beaconParams.ht20Coexist &&
1179 (eHT_CHANNEL_WIDTH_20MHZ ==
1180 sta_ds->htSupportedChannelWidthSet)) {
1181 lim_decide_ap_protection_on_ht20_delete(mac_ctx, sta_ds,
1182 beacon_params, session_entry);
1183 }
1184
1185 /*
1186 * Applies to 2.4 as well as 5 GHZ.
1187 * LSIG TXOP not supporting staiton leaving
1188 */
1189 if ((false == session_entry->beaconParams.
1190 fLsigTXOPProtectionFullSupport) &&
1191 (false == sta_ds->htLsigTXOPProtection)) {
1192 lim_log(mac_ctx, LOG1,
1193 FL("(%d) A HT LSIG not supporting STA is disassociated. Addr is %pM"),
1194 session_entry->gLimLsigTxopParams.numSta,
1195 sta_ds->staAddr);
1196 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1197 if (session_entry->protStaCache[i].active &&
1198 cdf_mem_compare(
1199 session_entry->protStaCache[i].addr,
1200 sta_ds->staAddr,
1201 sizeof(tSirMacAddr))) {
1202 session_entry->protStaCache[i].active = false;
1203 break;
1204 }
1205 }
1206
1207 if (session_entry->gLimLsigTxopParams.numSta == 0) {
1208 /* disable protection */
1209 lim_enable_ht_lsig_txop_protection(mac_ctx, true,
1210 false, beacon_params, session_entry);
1211 }
1212 }
1213}
1214
1215/**
1216 * lim_decide_short_preamble() - update short preamble parameters
1217 * @mac_ctx: pointer to global mac structure
1218 * @sta_ds: station node
1219 * @beacon_params: ap beacon parameters
1220 * @session_entry: pe session entry
1221 *
1222 * Decides about any short preamble related change because of new station
1223 * joining.
1224 *
1225 * Return: None
1226 */
1227void lim_decide_short_preamble(tpAniSirGlobal mac_ctx,
1228 tpDphHashNode sta_ds,
1229 tpUpdateBeaconParams beacon_params,
1230 tpPESession session_entry)
1231{
1232 uint32_t i;
1233
1234 if (sta_ds->shortPreambleEnabled == eHAL_CLEAR) {
1235 lim_log(mac_ctx, LOG1,
1236 FL("(%d) A non-short preamble STA is disassociated. Addr is %pM"),
1237 session_entry->gLimNoShortParams.numNonShortPreambleSta,
1238 sta_ds->staAddr);
1239 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1240 if (session_entry->gLimNoShortParams.
1241 staNoShortCache[i].active &&
1242 cdf_mem_compare(session_entry->
1243 gLimNoShortParams.
1244 staNoShortCache[i].addr,
1245 sta_ds->staAddr,
1246 sizeof(tSirMacAddr))) {
1247 session_entry->gLimNoShortParams.
1248 numNonShortPreambleSta--;
1249 session_entry->gLimNoShortParams.
1250 staNoShortCache[i].active = false;
1251 break;
1252 }
1253 }
1254
1255 if (session_entry->gLimNoShortParams.numNonShortPreambleSta)
1256 return;
1257
1258 /*
1259 * enable short preamble
1260 * reset the cache
1261 */
1262 cdf_mem_set((uint8_t *) &session_entry->gLimNoShortParams,
1263 sizeof(tLimNoShortParams), 0);
1264 if (lim_enable_short_preamble(mac_ctx, true,
1265 beacon_params, session_entry) != eSIR_SUCCESS) {
1266 lim_log(mac_ctx, LOGE,
1267 FL("Cannot enable short preamble"));
1268 }
1269 }
1270}
1271
1272/**
1273 * lim_decide_short_slot() - update short slot time related parameters
1274 * @mac_ctx: pointer to global mac structure
1275 * @sta_ds: station node
1276 * @beacon_params: ap beacon parameters
1277 * @session_entry: pe session entry
1278 *
1279 * Decides about any short slot time related change because of station leaving
1280 * the BSS.
1281 * Return: None
1282 */
1283void
1284lim_decide_short_slot(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
1285 tpUpdateBeaconParams beacon_params,
1286 tpPESession session_entry)
1287{
1288 uint32_t i, val, non_short_slot_sta_count;
1289
1290 if (sta_ds->shortSlotTimeEnabled != eHAL_CLEAR)
1291 return;
1292
1293 lim_log(mac_ctx, LOG1,
1294 FL("(%d) A non-short slottime STA is disassociated. Addr is %pM"),
1295 mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta,
1296 sta_ds->staAddr);
1297
1298 wlan_cfg_get_int(mac_ctx, WNI_CFG_11G_SHORT_SLOT_TIME_ENABLED,
1299 &val);
1300
1301 if (LIM_IS_AP_ROLE(session_entry)) {
1302 non_short_slot_sta_count =
1303 session_entry->gLimNoShortSlotParams.numNonShortSlotSta;
1304 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1305 if (session_entry->gLimNoShortSlotParams.
1306 staNoShortSlotCache[i].active &&
1307 cdf_mem_compare(session_entry->
1308 gLimNoShortSlotParams.
1309 staNoShortSlotCache[i].addr,
1310 sta_ds->staAddr,
1311 sizeof(tSirMacAddr))) {
1312 non_short_slot_sta_count--;
1313 session_entry->gLimNoShortSlotParams.
1314 staNoShortSlotCache[i].active = false;
1315 break;
1316 }
1317 }
1318
1319 if (non_short_slot_sta_count == 0 && val) {
1320 /*
1321 * enable short slot time
1322 * reset the cache
1323 */
1324 cdf_mem_set((uint8_t *) &session_entry->
1325 gLimNoShortSlotParams,
1326 sizeof(tLimNoShortSlotParams), 0);
1327 beacon_params->fShortSlotTime = true;
1328 beacon_params->paramChangeBitmap |=
1329 PARAM_SHORT_SLOT_TIME_CHANGED;
1330 session_entry->shortSlotTimeSupported = true;
1331 }
1332 session_entry->gLimNoShortSlotParams.numNonShortSlotSta =
1333 non_short_slot_sta_count;
1334 } else {
1335 non_short_slot_sta_count =
1336 mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta;
1337 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1338 if (mac_ctx->lim.gLimNoShortSlotParams.
1339 staNoShortSlotCache[i].active &&
1340 cdf_mem_compare(
1341 mac_ctx->lim.gLimNoShortSlotParams.
1342 staNoShortSlotCache[i].addr,
1343 sta_ds->staAddr,
1344 sizeof(tSirMacAddr))) {
1345 non_short_slot_sta_count--;
1346 mac_ctx->lim.gLimNoShortSlotParams.
1347 staNoShortSlotCache[i].active = false;
1348 break;
1349 }
1350 }
1351
1352 if (val && !non_short_slot_sta_count) {
1353 /*
1354 * enable short slot time
1355 * reset the cache
1356 */
1357 cdf_mem_set(
1358 (uint8_t *) &mac_ctx->lim.gLimNoShortSlotParams,
1359 sizeof(tLimNoShortSlotParams), 0);
1360 /*in case of AP set SHORT_SLOT_TIME to enable*/
1361 if (LIM_IS_AP_ROLE(session_entry)) {
1362 beacon_params->fShortSlotTime = true;
1363 beacon_params->paramChangeBitmap |=
1364 PARAM_SHORT_SLOT_TIME_CHANGED;
1365 session_entry->shortSlotTimeSupported = true;
1366 }
1367 }
1368 mac_ctx->lim.gLimNoShortSlotParams.numNonShortSlotSta =
1369 non_short_slot_sta_count;
1370 }
1371}
1372
1373void
1374lim_post_reassoc_failure(tpAniSirGlobal pMac,
1375 tSirResultCodes resultCode,
1376 uint16_t protStatusCode, tpPESession psessionEntry)
1377{
1378 tLimMlmReassocCnf mlmReassocCnf;
1379
1380 psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
1381 MTRACE(mac_trace
1382 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
1383 eLIM_MLM_LINK_ESTABLISHED_STATE));
1384
1385 /* 'Change' timer for future activations */
1386 lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
1387
1388 mlmReassocCnf.resultCode = resultCode;
1389 mlmReassocCnf.protStatusCode = protStatusCode;
1390 /* Update PE session Id */
1391 mlmReassocCnf.sessionId = psessionEntry->peSessionId;
1392 lim_post_sme_message(pMac,
1393 LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
1394} /*** end lim_post_reassoc_failure() ***/
1395
1396/**
1397 * lim_restore_pre_reassoc_state()
1398 *
1399 ***FUNCTION:
1400 * This function is called on STA role whenever Reasociation
1401 * Response with a reject code is received from AP.
1402 *
1403 ***LOGIC:
1404 * Reassociation failure timer is stopped, Old (or current) AP's
1405 * context is restored both at Polaris & software
1406 *
1407 ***ASSUMPTIONS:
1408 *
1409 ***NOTE:
1410 *
1411 * @param pMac - Pointer to Global MAC structure
1412 * @param resultCode - Result code that specifies why Reassociation
1413 * attemp failed
1414 *
1415 * @return None
1416 */
1417
1418void
1419lim_restore_pre_reassoc_state(tpAniSirGlobal pMac,
1420 tSirResultCodes resultCode,
1421 uint16_t protStatusCode, tpPESession psessionEntry)
1422{
1423 tLimMlmReassocCnf mlmReassocCnf;
1424
1425 lim_log(pMac, LOG1,
1426 FL("sessionid: %d protStatusCode: %d resultCode: %d"),
1427 psessionEntry->smeSessionId, protStatusCode, resultCode);
1428
1429 psessionEntry->limMlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
1430 MTRACE(mac_trace
1431 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
1432 eLIM_MLM_LINK_ESTABLISHED_STATE));
1433
1434 /* 'Change' timer for future activations */
1435 lim_deactivate_and_change_timer(pMac, eLIM_REASSOC_FAIL_TIMER);
1436
1437 lim_set_channel(pMac, psessionEntry->currentOperChannel,
1438 psessionEntry->ch_center_freq_seg0,
1439 psessionEntry->ch_center_freq_seg1,
1440 psessionEntry->ch_width,
1441 psessionEntry->maxTxPower,
1442 psessionEntry->peSessionId);
1443
1444 /** @ToDo : Need to Integrate the STOP the DataTransfer to the AP from 11H code */
1445
1446 mlmReassocCnf.resultCode = resultCode;
1447 mlmReassocCnf.protStatusCode = protStatusCode;
1448 /* Update PE session Id */
1449 mlmReassocCnf.sessionId = psessionEntry->peSessionId;
1450 lim_post_sme_message(pMac,
1451 LIM_MLM_REASSOC_CNF, (uint32_t *) &mlmReassocCnf);
1452} /*** end lim_restore_pre_reassoc_state() ***/
1453
1454/**
1455 * lim_is_reassoc_in_progress()
1456 *
1457 ***FUNCTION:
1458 * This function is called to see if STA is in wt-reassoc-rsp state.
1459 *
1460 ***LOGIC:
1461 *
1462 ***ASSUMPTIONS:
1463 *
1464 ***NOTE:
1465 *
1466 * @param pMac - Pointer to Global MAC structure
1467 *
1468 * @return true When STA is waiting for Reassoc response from AP \n
1469 * else false
1470 */
1471
1472bool lim_is_reassoc_in_progress(tpAniSirGlobal pMac, tpPESession psessionEntry)
1473{
1474 if (psessionEntry == NULL) {
1475 return false;
1476 }
1477 if ((LIM_IS_STA_ROLE(psessionEntry) ||
1478 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) &&
1479 ((psessionEntry->limSmeState == eLIM_SME_WT_REASSOC_STATE) ||
1480 (psessionEntry->limSmeState ==
1481 eLIM_SME_WT_REASSOC_LINK_FAIL_STATE)))
1482 return true;
1483
1484 return false;
1485} /*** end lim_is_reassoc_in_progress() ***/
1486
1487#ifdef WLAN_FEATURE_11AC
1488/**
1489 * lim_populate_vht_mcs_set - function to populate vht mcs rate set
1490 * @mac_ctx: pointer to global mac structure
1491 * @rates: pointer to supported rate set
1492 * @peer_vht_caps: pointer to peer vht capabilities
1493 * @session_entry: pe session entry
1494 *
1495 * Populates vht mcs rate set based on peer and self capabilities
1496 *
1497 * Return: eSIR_SUCCESS on success else eSIR_FAILURE
1498 */
1499tSirRetStatus lim_populate_vht_mcs_set(tpAniSirGlobal mac_ctx,
1500 tpSirSupportedRates rates,
1501 tDot11fIEVHTCaps *peer_vht_caps,
1502 tpPESession session_entry)
1503{
1504 uint32_t val;
1505 uint32_t self_sta_dot11mode = 0;
1506 uint16_t mcs_map_mask = MCSMAPMASK1x1;
1507 uint16_t mcs_map_mask2x2 = 0;
1508
1509 wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
1510
1511 if (!IS_DOT11_MODE_VHT(self_sta_dot11mode))
1512 return eSIR_SUCCESS;
1513
1514 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_RX_MCS_MAP, &val) !=
1515 eSIR_SUCCESS) {
1516 lim_log(mac_ctx, LOGE, FL("could not retrieve VHT RX MCS MAP"));
1517 goto error;
1518 }
1519 rates->vhtRxMCSMap = (uint16_t) val;
1520
1521 if (wlan_cfg_get_int(mac_ctx, WNI_CFG_VHT_TX_MCS_MAP, &val) !=
1522 eSIR_SUCCESS) {
1523 lim_log(mac_ctx, LOGE, FL("could not retrieve VHT TX MCS MAP"));
1524 goto error;
1525 }
1526 rates->vhtTxMCSMap = (uint16_t) val;
1527
1528 if (wlan_cfg_get_int(mac_ctx,
1529 WNI_CFG_VHT_RX_HIGHEST_SUPPORTED_DATA_RATE,
1530 &val) != eSIR_SUCCESS) {
1531 lim_log(mac_ctx, LOGE,
1532 FL("couldn't retrieve VHT RX Supported data rate MAP"));
1533 goto error;
1534 }
1535 rates->vhtRxHighestDataRate = (uint16_t) val;
1536
1537 if (wlan_cfg_get_int(mac_ctx,
1538 WNI_CFG_VHT_TX_HIGHEST_SUPPORTED_DATA_RATE,
1539 &val) != eSIR_SUCCESS) {
1540 lim_log(mac_ctx, LOGE,
1541 FL("couldn't retrieve VHT RX Supported data rate MAP"));
1542 goto error;
1543 }
1544 rates->vhtTxHighestDataRate = (uint16_t) val;
1545
1546 if (peer_vht_caps == NULL)
1547 return eSIR_SUCCESS;
1548
1549 rates->vhtTxHighestDataRate =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301550 QDF_MIN(rates->vhtTxHighestDataRate,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001551 peer_vht_caps->txSupDataRate);
1552 rates->vhtRxHighestDataRate =
Anurag Chouhan6d760662016-02-20 16:05:43 +05301553 QDF_MIN(rates->vhtRxHighestDataRate,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554 peer_vht_caps->rxHighSupDataRate);
1555
1556 if (mac_ctx->roam.configParam.enable2x2) {
1557 if (session_entry && mac_ctx->lteCoexAntShare &&
1558 IS_24G_CH(session_entry->currentOperChannel)) {
1559 if (IS_2X2_CHAIN(session_entry->chainMask))
1560 mcs_map_mask2x2 = MCSMAPMASK2x2;
1561 else
1562 lim_log(mac_ctx, LOGE, FL("2x2 not enabled %d"),
1563 session_entry->chainMask);
1564 } else {
1565 mcs_map_mask2x2 = MCSMAPMASK2x2;
1566 }
1567 }
1568
1569 if ((peer_vht_caps->txMCSMap & mcs_map_mask) <
1570 (rates->vhtRxMCSMap & mcs_map_mask)) {
1571 rates->vhtRxMCSMap &= ~(mcs_map_mask);
1572 rates->vhtRxMCSMap |=
1573 (peer_vht_caps->txMCSMap & mcs_map_mask);
1574 }
1575 if ((peer_vht_caps->rxMCSMap & mcs_map_mask) <
1576 (rates->vhtTxMCSMap & mcs_map_mask)) {
1577 rates->vhtTxMCSMap &= ~(mcs_map_mask);
1578 rates->vhtTxMCSMap |=
1579 (peer_vht_caps->rxMCSMap & mcs_map_mask);
1580 }
1581
1582 if (mcs_map_mask2x2) {
1583
1584 uint16_t peer_mcs_map, self_mcs_map;
1585
1586 peer_mcs_map =
1587 peer_vht_caps->txMCSMap & mcs_map_mask2x2;
1588 self_mcs_map =
1589 rates->vhtRxMCSMap & mcs_map_mask2x2;
1590
1591 if ((self_mcs_map != mcs_map_mask2x2) &&
1592 ((peer_mcs_map == mcs_map_mask2x2) ||
1593 (peer_mcs_map < self_mcs_map))) {
1594 rates->vhtRxMCSMap &= ~mcs_map_mask2x2;
1595 rates->vhtRxMCSMap |= peer_mcs_map;
1596 }
1597
1598 peer_mcs_map =
1599 (peer_vht_caps->rxMCSMap & mcs_map_mask2x2);
1600 self_mcs_map =
1601 (rates->vhtTxMCSMap & mcs_map_mask2x2);
1602
1603 if ((self_mcs_map != mcs_map_mask2x2) &&
1604 ((peer_mcs_map == mcs_map_mask2x2) ||
1605 (peer_mcs_map < self_mcs_map))) {
1606 rates->vhtTxMCSMap &= ~mcs_map_mask2x2;
1607 rates->vhtTxMCSMap |= peer_mcs_map;
1608 }
1609 }
1610
1611 lim_log(mac_ctx, LOG1,
1612 FL("enable2x2 - %d vhtRxMCSMap - %x vhtTxMCSMap - %x\n"),
1613 mac_ctx->roam.configParam.enable2x2,
1614 rates->vhtRxMCSMap, rates->vhtTxMCSMap);
1615
1616 return eSIR_SUCCESS;
1617error:
1618
1619 return eSIR_FAILURE;
1620}
1621#endif
1622
1623/**
1624 * lim_populate_own_rate_set() - comprises the basic and extended rates read
1625 * from CFG
1626 * @mac_ctx: pointer to global mac structure
1627 * @rates: pointer to supported rates
1628 * @supported_mcs_set: pointer to supported mcs rates
1629 * @basic_only: update only basic rates if set true
1630 * @session_entry: pe session entry
1631 * @vht_caps: pointer to vht capability
1632 *
1633 * This function is called by limProcessAssocRsp() or
1634 * lim_add_staInIBSS()
1635 * - It creates a combined rate set of 12 rates max which
1636 * comprises the basic and extended rates read from CFG
1637 * - It sorts the combined rate Set and copy it in the
1638 * rate array of the pSTA descriptor
1639 * - It sets the erpEnabled bit of the STA descriptor
1640 * ERP bit is set iff the dph PHY mode is 11G and there is at least
1641 * an A rate in the supported or extended rate sets
1642 *
1643 * Return: eSIR_SUCCESS or eSIR_FAILURE.
1644 */
1645#ifdef WLAN_FEATURE_11AC
1646tSirRetStatus
1647lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
1648 tpSirSupportedRates rates, uint8_t *supported_mcs_set,
1649 uint8_t basic_only, tpPESession session_entry,
1650 tDot11fIEVHTCaps *vht_caps)
1651#else
1652tSirRetStatus
1653lim_populate_own_rate_set(tpAniSirGlobal mac_ctx,
1654 tpSirSupportedRates rates,
1655 uint8_t *supported_mcs_set,
1656 uint8_t basic_only, tpPESession session_entry)
1657#endif
1658{
1659 tSirMacRateSet temp_rate_set;
1660 tSirMacRateSet temp_rate_set2;
1661 uint32_t i, j, val, min, is_arate;
1662 uint32_t phy_mode = 0;
1663 uint32_t self_sta_dot11mode = 0;
1664 uint8_t a_rate_index = 0;
1665 uint8_t b_rate_index = 0;
1666
1667
1668 is_arate = 0;
1669
1670 wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &self_sta_dot11mode);
1671 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
1672
1673 /*
1674 * Include 11b rates only when the device configured in
1675 * auto, 11a/b/g or 11b_only
1676 */
1677 if ((self_sta_dot11mode == WNI_CFG_DOT11_MODE_ALL) ||
1678 (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11A) ||
1679 (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
1680 (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11N) ||
1681 (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11G) ||
1682 (self_sta_dot11mode == WNI_CFG_DOT11_MODE_11B)) {
1683 val = WNI_CFG_SUPPORTED_RATES_11B_LEN;
1684 wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11B,
1685 (uint8_t *) &temp_rate_set.rate, &val);
1686 temp_rate_set.numRates = (uint8_t) val;
1687 } else {
1688 temp_rate_set.numRates = 0;
1689 }
1690
1691 /* Include 11a rates when the device configured in non-11b mode */
1692 if (!IS_DOT11_MODE_11B(self_sta_dot11mode)) {
1693 val = WNI_CFG_SUPPORTED_RATES_11A_LEN;
1694 wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_RATES_11A,
1695 (uint8_t *) &temp_rate_set2.rate, &val);
1696 temp_rate_set2.numRates = (uint8_t) val;
1697 } else {
1698 temp_rate_set2.numRates = 0;
1699 }
1700
1701 if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
1702 /* we are in big trouble */
1703 lim_log(mac_ctx, LOGP, FL("more than 12 rates in CFG"));
1704 /* panic */
1705 goto error;
1706 }
1707 /* copy all rates in temp_rate_set, there are 12 rates max */
1708 for (i = 0; i < temp_rate_set2.numRates; i++)
1709 temp_rate_set.rate[i + temp_rate_set.numRates] =
1710 temp_rate_set2.rate[i];
1711
1712 temp_rate_set.numRates += temp_rate_set2.numRates;
1713
1714 /**
1715 * Sort rates in temp_rate_set (they are likely to be already sorted)
1716 * put the result in pSupportedRates
1717 */
1718
1719 cdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
1720 for (i = 0; i < temp_rate_set.numRates; i++) {
1721 min = 0;
1722 val = 0xff;
1723 is_arate = 0;
1724
1725 for (j = 0; (j < temp_rate_set.numRates) &&
1726 (j < SIR_MAC_RATESET_EID_MAX); j++) {
1727 if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) <
1728 val) {
1729 val = temp_rate_set.rate[j] & 0x7f;
1730 min = j;
1731 }
1732 }
1733
1734 if (sirIsArate(temp_rate_set.rate[min] & 0x7f))
1735 is_arate = 1;
1736
1737 /*
1738 * HAL needs to know whether the rate is basic rate or
1739 * not, as it needs to update the response rate table
1740 * accordingly. e.g. if one of the 11a rates is
1741 * basic rate, then that rate can be used for sending
1742 * control frames.
1743 * HAL updates the response rate table whenever basic
1744 * rate set is changed.
1745 */
1746 if (basic_only && temp_rate_set.rate[min] & 0x80) {
1747 if (is_arate)
1748 rates->llaRates[a_rate_index++] =
1749 temp_rate_set.rate[min];
1750 else
1751 rates->llbRates[b_rate_index++] =
1752 temp_rate_set.rate[min];
1753 } else {
1754 if (is_arate)
1755 rates->llaRates[a_rate_index++] =
1756 temp_rate_set.rate[min];
1757 else
1758 rates->llbRates[b_rate_index++] =
1759 temp_rate_set.rate[min];
1760 }
1761 temp_rate_set.rate[min] = 0xff;
1762 }
1763
1764 if (IS_DOT11_MODE_HT(self_sta_dot11mode)) {
1765 val = SIZE_OF_SUPPORTED_MCS_SET;
1766 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
1767 rates->supportedMCSSet,
1768 &val) != eSIR_SUCCESS) {
1769 /* Could not get rateset from CFG. Log error. */
1770 lim_log(mac_ctx, LOGE,
1771 FL("could not retrieve supportedMCSSet"));
1772 goto error;
1773 }
1774
1775 /*
1776 * if supported MCS Set of the peer is passed in,
1777 * then do the intersection
1778 * else use the MCS set from local CFG.
1779 */
1780
1781 if (supported_mcs_set != NULL) {
1782 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
1783 rates->supportedMCSSet[i] &=
1784 supported_mcs_set[i];
1785 }
1786
1787 lim_log(mac_ctx, LOG2, FL("MCS Rate Set Bitmap: "));
1788 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
1789 PELOG2(lim_log(mac_ctx, LOG2, FL("%x "),
1790 rates->supportedMCSSet[i]);)
1791 }
1792#ifdef WLAN_FEATURE_11AC
1793 lim_populate_vht_mcs_set(mac_ctx, rates, vht_caps, session_entry);
1794#endif
1795
1796 return eSIR_SUCCESS;
1797error:
1798 return eSIR_FAILURE;
1799}
1800
1801#ifdef WLAN_FEATURE_11AC
1802tSirRetStatus
1803lim_populate_peer_rate_set(tpAniSirGlobal pMac,
1804 tpSirSupportedRates pRates,
1805 uint8_t *pSupportedMCSSet,
1806 uint8_t basicOnly,
1807 tpPESession psessionEntry, tDot11fIEVHTCaps *pVHTCaps)
1808#else
1809tSirRetStatus
1810lim_populate_peer_rate_set(tpAniSirGlobal pMac,
1811 tpSirSupportedRates pRates,
1812 uint8_t *pSupportedMCSSet,
1813 uint8_t basicOnly, tpPESession psessionEntry)
1814#endif
1815{
1816 tSirMacRateSet tempRateSet;
1817 tSirMacRateSet tempRateSet2;
1818 uint32_t i, j, val, min, isArate;
1819 isArate = 0;
1820
1821 /* copy operational rate set from psessionEntry */
1822 if (psessionEntry->rateSet.numRates <= SIR_MAC_RATESET_EID_MAX) {
1823 cdf_mem_copy((uint8_t *) tempRateSet.rate,
1824 (uint8_t *) (psessionEntry->rateSet.rate),
1825 psessionEntry->rateSet.numRates);
1826 tempRateSet.numRates = psessionEntry->rateSet.numRates;
1827 } else {
1828 lim_log(pMac, LOGE,
1829 FL("more than SIR_MAC_RATESET_EID_MAX rates\n"));
1830 goto error;
1831 }
1832 if ((psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11G) ||
1833 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11A) ||
1834 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11AC) ||
1835 (psessionEntry->dot11mode == WNI_CFG_DOT11_MODE_11N)) {
1836 if (psessionEntry->extRateSet.numRates <=
1837 SIR_MAC_RATESET_EID_MAX) {
1838 cdf_mem_copy((uint8_t *) tempRateSet2.rate,
1839 (uint8_t *) (psessionEntry->extRateSet.
1840 rate),
1841 psessionEntry->extRateSet.numRates);
1842 tempRateSet2.numRates =
1843 psessionEntry->extRateSet.numRates;
1844 } else {
1845 lim_log(pMac, LOGE,
1846 FL
1847 ("psessionEntry->extRateSet.numRates more than SIR_MAC_RATESET_EID_MAX rates\n"));
1848 goto error;
1849 }
1850 } else
1851 tempRateSet2.numRates = 0;
1852 if ((tempRateSet.numRates + tempRateSet2.numRates) >
1853 SIR_MAC_RATESET_EID_MAX) {
1854 /* we are in big trouble */
1855 lim_log(pMac, LOGP, FL("more than 12 rates in CFG"));
1856 goto error;
1857 }
1858
1859 /* copy all rates in tempRateSet, there are 12 rates max */
1860 for (i = 0; i < tempRateSet2.numRates; i++)
1861 tempRateSet.rate[i + tempRateSet.numRates] =
1862 tempRateSet2.rate[i];
1863 tempRateSet.numRates += tempRateSet2.numRates;
1864 /**
1865 * Sort rates in tempRateSet (they are likely to be already sorted)
1866 * put the result in pSupportedRates
1867 */
1868 {
1869 uint8_t aRateIndex = 0;
1870 uint8_t bRateIndex = 0;
1871 cdf_mem_set((uint8_t *) pRates, sizeof(tSirSupportedRates), 0);
1872 for (i = 0; i < tempRateSet.numRates; i++) {
1873 min = 0;
1874 val = 0xff;
1875 isArate = 0;
1876 for (j = 0;
1877 (j < tempRateSet.numRates)
1878 && (j < SIR_MAC_RATESET_EID_MAX); j++) {
1879 if ((uint32_t) (tempRateSet.rate[j] & 0x7f) <
1880 val) {
1881 val = tempRateSet.rate[j] & 0x7f;
1882 min = j;
1883 }
1884 }
1885 if (sirIsArate(tempRateSet.rate[min] & 0x7f))
1886 isArate = 1;
1887 /*
1888 * HAL needs to know whether the rate is basic rate or not, as it needs to
1889 * update the response rate table accordingly. e.g. if one of the 11a rates is
1890 * basic rate, then that rate can be used for sending control frames.
1891 * HAL updates the response rate table whenever basic rate set is changed.
1892 */
1893 if (basicOnly) {
1894 if (tempRateSet.rate[min] & 0x80) {
1895 if (isArate)
1896 pRates->llaRates[aRateIndex++] =
1897 tempRateSet.rate[min];
1898 else
1899 pRates->llbRates[bRateIndex++] =
1900 tempRateSet.rate[min];
1901 }
1902 } else {
1903 if (isArate)
1904 pRates->llaRates[aRateIndex++] =
1905 tempRateSet.rate[min];
1906 else
1907 pRates->llbRates[bRateIndex++] =
1908 tempRateSet.rate[min];
1909 }
1910 tempRateSet.rate[min] = 0xff;
1911 }
1912 }
1913
1914 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
1915 val = SIZE_OF_SUPPORTED_MCS_SET;
1916 if (wlan_cfg_get_str(pMac, WNI_CFG_SUPPORTED_MCS_SET,
1917 pRates->supportedMCSSet,
1918 &val) != eSIR_SUCCESS) {
1919 /* / Could not get rateset from CFG. Log error. */
1920 PELOGE(lim_log
1921 (pMac, LOGE,
1922 FL("could not retrieve supportedMCSSet"));
1923 )
1924 goto error;
1925 }
1926 /* if supported MCS Set of the peer is passed in, then do the intersection */
1927 /* else use the MCS set from local CFG. */
1928 if (pSupportedMCSSet != NULL) {
1929 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
1930 pRates->supportedMCSSet[i] &=
1931 pSupportedMCSSet[i];
1932 }
1933 PELOG2(lim_log(pMac, LOG2, FL("MCS Rate Set Bitmap: "));)
1934 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++)
1935 PELOG2(lim_log
1936 (pMac, LOG2, FL("%x "),
1937 pRates->supportedMCSSet[i]);
1938 )
1939 }
1940#ifdef WLAN_FEATURE_11AC
1941 lim_populate_vht_mcs_set(pMac, pRates, pVHTCaps, psessionEntry);
1942#endif
1943 return eSIR_SUCCESS;
1944error:
1945 return eSIR_FAILURE;
1946} /*** lim_populate_peer_rate_set() ***/
1947
1948/**
1949 * lim_populate_matching_rate_set() -process the CFG rate sets and
1950 * the rate sets received in the Assoc request on AP.
1951 * @mac_ctx: pointer to global mac structure
1952 * @sta_ds: station node
1953 * @oper_rate_set: pointer to operating rate set
1954 * @ext_rate_set: pointer to extended rate set
1955 * @supported_mcs_set: pointer to supported rate set
1956 * @session_entry: pointer to pe session entry
1957 * @vht_caps: pointer to vht capabilities
1958 *
1959 * This is called at the time of Association Request
1960 * processing on AP and while adding peer's context
1961 * in IBSS role to process the CFG rate sets and
1962 * the rate sets received in the Assoc request on AP
1963 * or Beacon/Probe Response from peer in IBSS.
1964 *
1965 * 1. It makes the intersection between our own rate Sat
1966 * and extemcded rate set and the ones received in the
1967 * association request.
1968 * 2. It creates a combined rate set of 12 rates max which
1969 * comprised the basic and extended rates
1970 * 3. It sorts the combined rate Set and copy it in the
1971 * rate array of the pSTA descriptor
1972 *
1973 * The parser has already ensured unicity of the rates in the
1974 * association request structure
1975 *
1976 * Return: eSIR_SUCCESS on success else eSIR_FAILURE
1977 */
1978#ifdef WLAN_FEATURE_11AC
1979tSirRetStatus
1980lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
1981 tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
1982 uint8_t *supported_mcs_set, tpPESession session_entry,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301983 tDot11fIEVHTCaps *vht_caps)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001984#else
1985tSirRetStatus
1986lim_populate_matching_rate_set(tpAniSirGlobal mac_ctx, tpDphHashNode sta_ds,
1987 tSirMacRateSet *oper_rate_set, tSirMacRateSet *ext_rate_set,
1988 uint8_t *supported_mcs_set, tpPESession session_entry)
1989#endif
1990{
1991 tSirMacRateSet temp_rate_set;
1992 tSirMacRateSet temp_rate_set2;
1993 uint32_t i, j, val, min, is_arate;
1994 uint32_t phy_mode;
1995 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
1996 tpSirSupportedRates rates;
1997 uint8_t a_rate_index = 0;
1998 uint8_t b_rate_index = 0;
1999
2000 is_arate = 0;
2001
2002 lim_get_phy_mode(mac_ctx, &phy_mode, session_entry);
2003
2004 /* copy operational rate set from session_entry */
2005 cdf_mem_copy((temp_rate_set.rate), (session_entry->rateSet.rate),
2006 session_entry->rateSet.numRates);
2007 temp_rate_set.numRates = (uint8_t) session_entry->rateSet.numRates;
2008
2009 if (phy_mode == WNI_CFG_PHY_MODE_11G) {
2010 cdf_mem_copy((temp_rate_set2.rate),
2011 (session_entry->extRateSet.rate),
2012 session_entry->extRateSet.numRates);
2013 temp_rate_set2.numRates =
2014 (uint8_t) session_entry->extRateSet.numRates;
2015 } else {
2016 temp_rate_set2.numRates = 0;
2017 }
2018
2019 if ((temp_rate_set.numRates + temp_rate_set2.numRates) > 12) {
2020 lim_log(mac_ctx, LOGE, FL("more than 12 rates in CFG"));
2021 goto error;
2022 }
2023
2024 /*
2025 * Handling of the rate set IEs is the following:
2026 * - keep only rates that we support and that the station supports
2027 * - sort and the rates into the pSta->rate array
2028 */
2029
2030 /* Copy all rates in temp_rate_set, there are 12 rates max */
2031 for (i = 0; i < temp_rate_set2.numRates; i++)
2032 temp_rate_set.rate[i + temp_rate_set.numRates] =
2033 temp_rate_set2.rate[i];
2034
2035 temp_rate_set.numRates += temp_rate_set2.numRates;
2036
2037 /*
2038 * Sort rates in temp_rate_set (they are likely to be already sorted)
2039 * put the result in temp_rate_set2
2040 */
2041 temp_rate_set2.numRates = 0;
2042
2043 for (i = 0; i < temp_rate_set.numRates; i++) {
2044 min = 0;
2045 val = 0xff;
2046
2047 for (j = 0; j < temp_rate_set.numRates; j++)
2048 if ((uint32_t) (temp_rate_set.rate[j] & 0x7f) < val) {
2049 val = temp_rate_set.rate[j] & 0x7f;
2050 min = j;
2051 }
2052
2053 temp_rate_set2.rate[temp_rate_set2.numRates++] =
2054 temp_rate_set.rate[min];
2055 temp_rate_set.rate[min] = 0xff;
2056 }
2057
2058 /*
2059 * Copy received rates in temp_rate_set, the parser has ensured
2060 * unicity of the rates so there cannot be more than 12
2061 */
2062 for (i = 0; (i < oper_rate_set->numRates &&
2063 i < SIR_MAC_RATESET_EID_MAX); i++)
2064 temp_rate_set.rate[i] = oper_rate_set->rate[i];
2065
2066 temp_rate_set.numRates = oper_rate_set->numRates;
2067
2068 lim_log(mac_ctx, LOG2,
2069 "Sum of SUPPORTED and EXTENDED Rate Set (%1d)",
2070 temp_rate_set.numRates + ext_rate_set->numRates);
2071
2072 if (ext_rate_set->numRates &&
2073 ((temp_rate_set.numRates + ext_rate_set->numRates) > 12) &&
2074 temp_rate_set.numRates < 12) {
2075 int found = 0;
2076 int tail = temp_rate_set.numRates;
2077
2078 for (i = 0; (i < ext_rate_set->numRates &&
2079 i < SIR_MAC_RATESET_EID_MAX); i++) {
2080 found = 0;
2081 for (j = 0; j < (uint32_t) tail; j++) {
2082 if ((temp_rate_set.rate[j] & 0x7F) ==
2083 (ext_rate_set->rate[i] & 0x7F)) {
2084 found = 1;
2085 break;
2086 }
2087 }
2088
2089 if (!found) {
2090 temp_rate_set.rate[temp_rate_set.numRates++] =
2091 ext_rate_set->rate[i];
2092 if (temp_rate_set.numRates >= 12)
2093 break;
2094 }
2095 }
2096 } else if (ext_rate_set->numRates &&
2097 ((temp_rate_set.numRates + ext_rate_set->numRates) <= 12)) {
2098 for (j = 0; ((j < ext_rate_set->numRates) &&
2099 (j < SIR_MAC_RATESET_EID_MAX) &&
2100 ((i + j) < SIR_MAC_RATESET_EID_MAX)); j++)
2101 temp_rate_set.rate[i + j] = ext_rate_set->rate[j];
2102
2103 temp_rate_set.numRates += ext_rate_set->numRates;
2104 } else if (ext_rate_set->numRates) {
2105 lim_log(mac_ctx, LOG2,
2106 "Relying only on the SUPPORTED Rate Set IE...");
2107 }
2108
2109
2110 rates = &sta_ds->supportedRates;
2111 cdf_mem_set((uint8_t *) rates, sizeof(tSirSupportedRates), 0);
2112 for (i = 0; (i < temp_rate_set2.numRates &&
2113 i < SIR_MAC_RATESET_EID_MAX); i++) {
2114 for (j = 0; (j < temp_rate_set.numRates &&
2115 j < SIR_MAC_RATESET_EID_MAX); j++) {
2116 if ((temp_rate_set2.rate[i] & 0x7F) !=
2117 (temp_rate_set.rate[j] & 0x7F))
2118 continue;
2119
2120 if (sirIsArate(temp_rate_set2.rate[i] & 0x7f) &&
2121 a_rate_index < SIR_NUM_11A_RATES) {
2122 is_arate = 1;
2123 rates->llaRates[a_rate_index++] =
2124 temp_rate_set2.rate[i];
2125 } else if ((b_rate_index < SIR_NUM_11B_RATES) &&
2126 !(sirIsArate(temp_rate_set2.rate[i] & 0x7f))) {
2127 rates->llbRates[b_rate_index++] =
2128 temp_rate_set2.rate[i];
2129 }
2130 break;
2131 }
2132 }
2133
2134 /*
2135 * Now add the Polaris rates only when Proprietary rates are enabled.
2136 * compute the matching MCS rate set, if peer is 11n capable and self
2137 * mode is 11n
2138 */
2139#ifdef FEATURE_WLAN_TDLS
2140 if (sta_ds->mlmStaContext.htCapability)
2141#else
2142 if (IS_DOT11_MODE_HT(session_entry->dot11mode) &&
2143 (sta_ds->mlmStaContext.htCapability))
2144#endif
2145 {
2146 val = SIZE_OF_SUPPORTED_MCS_SET;
2147 if (wlan_cfg_get_str(mac_ctx, WNI_CFG_SUPPORTED_MCS_SET,
2148 mcs_set, &val) != eSIR_SUCCESS) {
2149 /* Could not get rateset from CFG. Log error. */
2150 lim_log(mac_ctx, LOGP,
2151 FL("could not retrieve supportedMCSet"));
2152 goto error;
2153 }
2154
2155 for (i = 0; i < val; i++)
2156 sta_ds->supportedRates.supportedMCSSet[i] =
2157 mcs_set[i] & supported_mcs_set[i];
2158
2159 lim_log(mac_ctx, LOG2,
2160 FL("lim_populate_matching_rate_set: MCS Rate Set Bitmap"
2161 " from CFG and DPH : "));
2162 for (i = 0; i < SIR_MAC_MAX_SUPPORTED_MCS_SET; i++) {
2163 lim_log(mac_ctx, LOG2, FL("%x %x "), mcs_set[i],
2164 sta_ds->supportedRates.supportedMCSSet[i]);
2165 }
2166 }
2167#ifdef WLAN_FEATURE_11AC
2168 lim_populate_vht_mcs_set(mac_ctx, &sta_ds->supportedRates, vht_caps,
2169 session_entry);
2170#endif
2171 /*
2172 * Set the erpEnabled bit if the phy is in G mode and at least
2173 * one A rate is supported
2174 */
2175 if ((phy_mode == WNI_CFG_PHY_MODE_11G) && is_arate)
2176 sta_ds->erpEnabled = eHAL_SET;
2177
2178 return eSIR_SUCCESS;
2179
2180error:
2181
2182 return eSIR_FAILURE;
2183}
2184
2185/**
2186 * lim_populate_vht_caps() - populates vht capabilities based on input
2187 * capabilities
2188 * @input_caps: input capabilities based on which we format the vht
2189 * capabilities
2190 *
2191 * function to populate the supported vht capabilities.
2192 *
2193 * Return: vht capabilities derived based on input parameters.
2194 */
2195static uint32_t lim_populate_vht_caps(tDot11fIEVHTCaps input_caps)
2196{
2197 uint32_t vht_caps;
2198
2199 vht_caps = ((input_caps.maxMPDULen << SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
2200 (input_caps.supportedChannelWidthSet <<
2201 SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
2202 (input_caps.ldpcCodingCap <<
2203 SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
2204 (input_caps.shortGI80MHz <<
2205 SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
2206 (input_caps.shortGI160and80plus80MHz <<
2207 SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
2208 (input_caps.txSTBC << SIR_MAC_VHT_CAP_TXSTBC) |
2209 (input_caps.rxSTBC << SIR_MAC_VHT_CAP_RXSTBC) |
2210 (input_caps.suBeamFormerCap <<
2211 SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
2212 (input_caps.suBeamformeeCap <<
2213 SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
2214 (input_caps.csnofBeamformerAntSup <<
2215 SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
2216 (input_caps.numSoundingDim <<
2217 SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
2218 (input_caps.muBeamformerCap <<
2219 SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
2220 (input_caps.muBeamformeeCap <<
2221 SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
2222 (input_caps.vhtTXOPPS <<
2223 SIR_MAC_VHT_CAP_TXOPPS) |
2224 (input_caps.htcVHTCap <<
2225 SIR_MAC_VHT_CAP_HTC_CAP) |
2226 (input_caps.maxAMPDULenExp <<
2227 SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
2228 (input_caps.vhtLinkAdaptCap <<
2229 SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
2230 (input_caps.rxAntPattern <<
2231 SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
2232 (input_caps.txAntPattern <<
2233 SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
2234 (input_caps.reserved1 <<
2235 SIR_MAC_VHT_CAP_RESERVED2));
2236
2237 return vht_caps;
2238}
2239/**
2240 * lim_add_sta()- called to add an STA context at hardware
2241 * @mac_ctx: pointer to global mac structure
2242 * @sta_ds: station node
2243 * @update_entry: set to true for updating the entry
2244 * @session_entry: pe session entry
2245 *
2246 * This function is called to add an STA context at hardware
2247 * whenever a STA is (Re) Associated.
2248 *
2249 * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
2250 */
2251
2252tSirRetStatus
2253lim_add_sta(tpAniSirGlobal mac_ctx,
2254 tpDphHashNode sta_ds, uint8_t update_entry, tpPESession session_entry)
2255{
2256 tpAddStaParams add_sta_params = NULL;
2257 tSirMsgQ msg_q;
2258 tSirRetStatus ret_code = eSIR_SUCCESS;
2259 tSirMacAddr sta_mac, *sta_Addr;
2260 uint8_t i, nw_type_11b = 0;
2261 tpSirAssocReq assoc_req;
2262 tLimIbssPeerNode *peer_node; /* for IBSS mode */
2263 uint8_t *p2p_ie = NULL;
2264
2265 sir_copy_mac_addr(sta_mac, session_entry->selfMacAddr);
2266
2267 lim_log(mac_ctx, LOG1,
2268 FL("sessionid: %d update_entry = %d limsystemrole = %d "),
2269 session_entry->smeSessionId, update_entry,
2270 GET_LIM_SYSTEM_ROLE(session_entry));
2271
2272 add_sta_params = cdf_mem_malloc(sizeof(tAddStaParams));
2273 if (NULL == add_sta_params) {
2274 lim_log(mac_ctx, LOGP,
2275 FL("Unable to allocate memory during ADD_STA"));
2276 return eSIR_MEM_ALLOC_FAILED;
2277 }
2278 cdf_mem_set((uint8_t *) add_sta_params, sizeof(tAddStaParams), 0);
2279
2280 if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry) ||
2281 LIM_IS_BT_AMP_AP_ROLE(session_entry))
2282 sta_Addr = &sta_ds->staAddr;
2283#ifdef FEATURE_WLAN_TDLS
2284 /* SystemRole shouldn't be matter if staType is TDLS peer */
2285 else if (STA_ENTRY_TDLS_PEER == sta_ds->staType)
2286 sta_Addr = &sta_ds->staAddr;
2287#endif
2288 else
2289 sta_Addr = &sta_mac;
2290
2291 lim_log(mac_ctx, LOG1,
2292 FL(MAC_ADDRESS_STR ": Subtype(Assoc/Reassoc): %d"),
2293 MAC_ADDR_ARRAY(*sta_Addr), sta_ds->mlmStaContext.subType);
2294
2295 cdf_mem_copy((uint8_t *) add_sta_params->staMac,
2296 (uint8_t *) *sta_Addr, sizeof(tSirMacAddr));
2297 cdf_mem_copy((uint8_t *) add_sta_params->bssId,
2298 session_entry->bssId, sizeof(tSirMacAddr));
2299 cdf_mem_copy(&add_sta_params->capab_info,
2300 &sta_ds->mlmStaContext.capabilityInfo,
2301 sizeof(add_sta_params->capab_info));
2302
2303 lim_fill_supported_rates_info(mac_ctx, sta_ds, &sta_ds->supportedRates,
2304 session_entry);
2305
2306 /* Copy legacy rates */
2307 cdf_mem_copy((uint8_t *) &add_sta_params->supportedRates,
2308 (uint8_t *) &sta_ds->supportedRates,
2309 sizeof(tSirSupportedRates));
2310
2311 add_sta_params->assocId = sta_ds->assocId;
2312
2313 add_sta_params->wmmEnabled = sta_ds->qosMode;
2314 add_sta_params->listenInterval = sta_ds->mlmStaContext.listenInterval;
2315 add_sta_params->shortPreambleSupported = sta_ds->shortPreambleEnabled;
2316 if (LIM_IS_AP_ROLE(session_entry) &&
2317 (sta_ds->mlmStaContext.subType == LIM_REASSOC)) {
2318 /*
2319 * TBD - need to remove this REASSOC check
2320 * after fixinf rmmod issue
2321 */
2322 add_sta_params->updateSta = sta_ds->mlmStaContext.updateContext;
2323 }
2324 sta_ds->valid = 0;
2325 sta_ds->mlmStaContext.mlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
2326
2327 lim_log(mac_ctx, LOG2,
2328 FL(" Assoc ID: %d wmmEnabled = %d listenInterval = %d"
2329 " shortPreambleSupported: %d "), add_sta_params->assocId,
2330 add_sta_params->wmmEnabled, add_sta_params->listenInterval,
2331 add_sta_params->shortPreambleSupported);
2332 /* This will indicate HAL to "allocate" a new STA index */
2333#ifdef FEATURE_WLAN_TDLS
2334 /*
2335 * As there is corner case in-between add_sta and change_sta,if del_sta
2336 * for other staIdx happened, firmware return wrong staIdx
2337 * (recently removed staIdx). Until we get a confirmation from the
2338 * firmware team it is now return correct staIdx for same sta_mac_addr
2339 * for update case, we want to get around it by passing valid staIdx
2340 * given by add_sta time.
2341 */
2342 if ((STA_ENTRY_TDLS_PEER == sta_ds->staType) && (true == update_entry))
2343 add_sta_params->staIdx = sta_ds->staIndex;
2344 else
2345#endif
2346 add_sta_params->staIdx = STA_INVALID_IDX;
2347 add_sta_params->staType = sta_ds->staType;
2348
2349 add_sta_params->updateSta = update_entry;
2350
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302351 add_sta_params->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352 add_sta_params->respReqd = 1;
2353 /* Update HT Capability */
2354
2355 if (LIM_IS_AP_ROLE(session_entry) ||
2356 LIM_IS_BT_AMP_AP_ROLE(session_entry) ||
2357 LIM_IS_IBSS_ROLE(session_entry)) {
2358 add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
2359#ifdef WLAN_FEATURE_11AC
2360 add_sta_params->vhtCapable =
2361 sta_ds->mlmStaContext.vhtCapability;
2362#endif
2363 }
2364#ifdef FEATURE_WLAN_TDLS
2365 /* SystemRole shouldn't be matter if staType is TDLS peer */
2366 else if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
2367 add_sta_params->htCapable = sta_ds->mlmStaContext.htCapability;
2368#ifdef WLAN_FEATURE_11AC
2369 add_sta_params->vhtCapable =
2370 sta_ds->mlmStaContext.vhtCapability;
2371#endif
2372 }
2373#endif
2374 else {
2375 add_sta_params->htCapable = session_entry->htCapability;
2376#ifdef WLAN_FEATURE_11AC
2377 add_sta_params->vhtCapable = session_entry->vhtCapability;
2378#endif
2379
2380 }
2381#ifdef WLAN_FEATURE_11AC
2382 lim_log(mac_ctx, LOG2, FL("vhtCapable: %d "),
2383 add_sta_params->vhtCapable);
2384#endif
2385 lim_log(mac_ctx, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
2386 add_sta_params->staIdx, add_sta_params->updateSta,
2387 add_sta_params->htCapable);
2388
2389 add_sta_params->greenFieldCapable = sta_ds->htGreenfield;
2390 add_sta_params->maxAmpduDensity = sta_ds->htAMpduDensity;
2391 add_sta_params->maxAmpduSize = sta_ds->htMaxRxAMpduFactor;
2392 add_sta_params->fDsssCckMode40Mhz = sta_ds->htDsssCckRate40MHzSupport;
2393 add_sta_params->fShortGI20Mhz = sta_ds->htShortGI20Mhz;
2394 add_sta_params->fShortGI40Mhz = sta_ds->htShortGI40Mhz;
2395 add_sta_params->lsigTxopProtection = sta_ds->htLsigTXOPProtection;
2396 add_sta_params->maxAmsduSize = sta_ds->htMaxAmsduLength;
2397 add_sta_params->ch_width = sta_ds->htSupportedChannelWidthSet;
2398 add_sta_params->mimoPS = sta_ds->htMIMOPSState;
2399
2400 lim_log(mac_ctx, LOG2,
2401 FL("greenFieldCapable: %d maxAmpduDensity = %d maxAmpduDensity = %d"),
2402 add_sta_params->greenFieldCapable,
2403 add_sta_params->maxAmpduDensity, add_sta_params->maxAmpduSize);
2404
2405 lim_log(mac_ctx, LOG2,
2406 FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d fShortGI40Mhz: %d"),
2407 add_sta_params->fDsssCckMode40Mhz,
2408 add_sta_params->fShortGI20Mhz, add_sta_params->fShortGI40Mhz);
2409
2410 lim_log(mac_ctx, LOG2,
2411 FL("lsigTxopProtection: %d maxAmsduSize: %d txChannelWidth: %d mimoPS: %d "),
2412 add_sta_params->lsigTxopProtection,
2413 add_sta_params->maxAmsduSize, add_sta_params->ch_width,
2414 add_sta_params->mimoPS);
2415
2416 if (add_sta_params->vhtCapable) {
2417 if (sta_ds->vhtSupportedChannelWidthSet)
2418 add_sta_params->ch_width =
2419 sta_ds->vhtSupportedChannelWidthSet + 1;
2420
2421 add_sta_params->vhtSupportedRxNss = sta_ds->vhtSupportedRxNss;
2422 add_sta_params->vhtTxBFCapable =
2423#ifdef FEATURE_WLAN_TDLS
2424 ((STA_ENTRY_PEER == sta_ds->staType)
2425 || (STA_ENTRY_TDLS_PEER == sta_ds->staType)) ?
2426 sta_ds->vhtBeamFormerCapable :
2427 session_entry->txBFIniFeatureEnabled;
2428#else
2429 (STA_ENTRY_PEER == sta_ds->staType) ?
2430 sta_ds->vhtBeamFormerCapable :
2431 session_entry->txBFIniFeatureEnabled;
2432#endif
2433 add_sta_params->enable_su_tx_bformer =
2434 sta_ds->vht_su_bfee_capable;
2435 }
2436
2437 lim_log(mac_ctx, LOGE, FL("TxChWidth %d vhtTxBFCap %d, su_bfer %d"),
2438 add_sta_params->ch_width, add_sta_params->vhtTxBFCapable,
2439 add_sta_params->enable_su_tx_bformer);
2440#ifdef FEATURE_WLAN_TDLS
2441 if ((STA_ENTRY_PEER == sta_ds->staType) ||
2442 (STA_ENTRY_TDLS_PEER == sta_ds->staType))
2443#else
2444 if (STA_ENTRY_PEER == sta_ds->staType)
2445#endif
2446 {
2447 /*
2448 * peer STA get the LDPC capability from sta_ds,
2449 * which populated from
2450 * HT/VHT capability
2451 */
2452 if (add_sta_params->vhtTxBFCapable
2453 && mac_ctx->lim.disableLDPCWithTxbfAP) {
2454 add_sta_params->htLdpcCapable = 0;
2455 add_sta_params->vhtLdpcCapable = 0;
2456 } else {
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08002457 if (session_entry->txLdpcIniFeatureEnabled & 0x1)
2458 add_sta_params->htLdpcCapable =
2459 sta_ds->htLdpcCapable;
2460 else
2461 add_sta_params->htLdpcCapable = 0;
2462
2463 if (session_entry->txLdpcIniFeatureEnabled & 0x2)
2464 add_sta_params->vhtLdpcCapable =
2465 sta_ds->vhtLdpcCapable;
2466 else
2467 add_sta_params->vhtLdpcCapable = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002468 }
2469 } else if (STA_ENTRY_SELF == sta_ds->staType) {
2470 /* For Self STA get the LDPC capability from config.ini */
2471 add_sta_params->htLdpcCapable =
2472 (session_entry->txLdpcIniFeatureEnabled & 0x01);
2473 add_sta_params->vhtLdpcCapable =
2474 ((session_entry->txLdpcIniFeatureEnabled >> 1) & 0x01);
2475 }
2476
2477 /* Update PE session ID */
2478 add_sta_params->sessionId = session_entry->peSessionId;
2479
2480 /* Update SME session ID */
2481 add_sta_params->smesessionId = session_entry->smeSessionId;
2482
2483 add_sta_params->maxTxPower = session_entry->maxTxPower;
2484
2485 if (session_entry->parsedAssocReq != NULL) {
2486 uint16_t aid = sta_ds->assocId;
2487 /* Get a copy of the already parsed Assoc Request */
2488 assoc_req =
2489 (tpSirAssocReq) session_entry->parsedAssocReq[aid];
2490 if (assoc_req && assoc_req->addIEPresent
2491 && assoc_req->addIE.length) {
2492 p2p_ie = limGetP2pIEPtr(mac_ctx,
2493 assoc_req->addIE.addIEdata,
2494 assoc_req->addIE.length);
2495 }
2496
2497 add_sta_params->p2pCapableSta = (p2p_ie != NULL);
2498 if (assoc_req && add_sta_params->htCapable) {
2499 cdf_mem_copy(&add_sta_params->ht_caps,
2500 ((uint8_t *) &assoc_req->HTCaps) + 1,
2501 sizeof(add_sta_params->ht_caps));
2502 }
2503
2504 if (assoc_req && add_sta_params->vhtCapable)
2505 add_sta_params->vht_caps =
2506 lim_populate_vht_caps(assoc_req->VHTCaps);
2507 } else if (LIM_IS_IBSS_ROLE(session_entry)) {
2508
2509 /*
2510 * in IBSS mode, use peer node as the source of ht_caps
2511 * and vht_caps
2512 */
2513 peer_node = lim_ibss_peer_find(mac_ctx, *sta_Addr);
2514 if (!peer_node) {
2515 lim_log(mac_ctx, LOGP,
2516 FL("Can't find IBSS peer node for ADD_STA"));
2517 return eSIR_HAL_STA_DOES_NOT_EXIST;
2518 }
2519
2520 if (peer_node->atimIePresent) {
2521 add_sta_params->atimIePresent =
2522 peer_node->atimIePresent;
2523 add_sta_params->peerAtimWindowLength =
2524 peer_node->peerAtimWindowLength;
2525 }
2526
2527 add_sta_params->ht_caps =
2528 (peer_node->htSupportedChannelWidthSet <<
2529 SIR_MAC_HT_CAP_CHWIDTH40_S) |
2530 (peer_node->htGreenfield <<
2531 SIR_MAC_HT_CAP_GREENFIELD_S) |
2532 (peer_node->htShortGI20Mhz <<
2533 SIR_MAC_HT_CAP_SHORTGI20MHZ_S) |
2534 (peer_node->htShortGI40Mhz <<
2535 SIR_MAC_HT_CAP_SHORTGI40MHZ_S) |
2536 (SIR_MAC_TXSTBC <<
2537 SIR_MAC_HT_CAP_TXSTBC_S) |
2538 (SIR_MAC_RXSTBC <<
2539 SIR_MAC_HT_CAP_RXSTBC_S) |
2540 (peer_node->htMaxAmsduLength <<
2541 SIR_MAC_HT_CAP_MAXAMSDUSIZE_S) |
2542 (peer_node->htDsssCckRate40MHzSupport <<
2543 SIR_MAC_HT_CAP_DSSSCCK40_S);
2544
2545 add_sta_params->vht_caps =
2546 lim_populate_vht_caps(peer_node->VHTCaps);
2547 }
2548#ifdef FEATURE_WLAN_TDLS
2549 if (STA_ENTRY_TDLS_PEER == sta_ds->staType) {
2550 add_sta_params->ht_caps = sta_ds->ht_caps;
2551 add_sta_params->vht_caps = sta_ds->vht_caps;
2552
2553 lim_log(mac_ctx, LOG1,
2554 FL("Sta type is TDLS_PEER, ht_caps: 0x%x, vht_caps: 0x%x"),
2555 add_sta_params->ht_caps,
2556 add_sta_params->vht_caps);
2557 }
2558#endif
2559
2560#ifdef FEATURE_WLAN_TDLS
2561 if (sta_ds->wmeEnabled &&
2562 (LIM_IS_AP_ROLE(session_entry) ||
2563 (STA_ENTRY_TDLS_PEER == sta_ds->staType)))
2564#else
2565 if (sta_ds->wmeEnabled && LIM_IS_AP_ROLE(session_entry))
2566#endif
2567 {
2568 add_sta_params->uAPSD = 0;
2569 /*
2570 * update UAPSD and send it to LIM to add STA
2571 * bitmap MSB <- LSB MSB 4 bits are for
2572 * trigger enabled AC setting and LSB 4 bits
2573 * are for delivery enabled AC setting
2574 * 7 6 5 4 3 2 1 0
2575 * BE BK VI VO BE BK VI VO
2576 */
2577 add_sta_params->uAPSD |=
2578 sta_ds->qos.capability.qosInfo.acvo_uapsd;
2579 add_sta_params->uAPSD |=
2580 (sta_ds->qos.capability.qosInfo.acvi_uapsd << 1);
2581 add_sta_params->uAPSD |=
2582 (sta_ds->qos.capability.qosInfo.acbk_uapsd << 2);
2583 add_sta_params->uAPSD |=
2584 (sta_ds->qos.capability.qosInfo.acbe_uapsd << 3);
2585 /*
2586 * making delivery enabled and
2587 * trigger enabled setting the same.
2588 */
2589 add_sta_params->uAPSD |= add_sta_params->uAPSD << 4;
2590
2591 add_sta_params->maxSPLen =
2592 sta_ds->qos.capability.qosInfo.maxSpLen;
2593 lim_log(mac_ctx, LOG1, FL("uAPSD = 0x%x, maxSpLen = %d"),
2594 add_sta_params->uAPSD, add_sta_params->maxSPLen);
2595 }
2596#ifdef WLAN_FEATURE_11W
2597 add_sta_params->rmfEnabled = sta_ds->rmfEnabled;
2598 lim_log(mac_ctx, LOG1, FL("PMF enabled %d"),
2599 add_sta_params->rmfEnabled);
2600#endif
2601
2602 lim_log(mac_ctx, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
2603 "p2pCapableSta: %d"),
2604 add_sta_params->htLdpcCapable, add_sta_params->vhtLdpcCapable,
2605 add_sta_params->p2pCapableSta);
2606
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08002607 if (!add_sta_params->htLdpcCapable)
2608 add_sta_params->ht_caps &= ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
2609 if (!add_sta_params->vhtLdpcCapable)
2610 add_sta_params->vht_caps &=
2611 ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);
2612
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002613 /*
2614 * we need to defer the message until we get the
2615 * response back from HAL.
2616 */
2617 if (add_sta_params->respReqd)
2618 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, false);
2619
2620 for (i = 0; i < SIR_NUM_11A_RATES; i++) {
2621 if (sirIsArate(sta_ds->supportedRates.llaRates[i] & 0x7F)) {
2622 nw_type_11b = 0;
2623 break;
2624 } else {
2625 nw_type_11b = 1;
2626 }
2627 }
2628 if (nw_type_11b)
2629 add_sta_params->nwType = eSIR_11B_NW_TYPE;
2630 else
2631 add_sta_params->nwType = session_entry->nwType;
2632
2633 msg_q.type = WMA_ADD_STA_REQ;
2634
2635 msg_q.reserved = 0;
2636 msg_q.bodyptr = add_sta_params;
2637 msg_q.bodyval = 0;
2638
2639 lim_log(mac_ctx, LOG1, FL("Sending WMA_ADD_STA_REQ for assocId %d"),
2640 sta_ds->assocId);
2641 MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
2642 msg_q.type));
2643
2644 ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
2645 if (eSIR_SUCCESS != ret_code) {
2646 if (add_sta_params->respReqd)
2647 SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true);
2648 lim_log(mac_ctx, LOGE,
2649 FL("ADD_STA_REQ for aId %d failed (reason %X)"),
2650 sta_ds->assocId, ret_code);
2651 cdf_mem_free(add_sta_params);
2652 }
2653
2654 return ret_code;
2655}
2656
2657/**
2658 * lim_del_sta()
2659 *
2660 ***FUNCTION:
2661 * This function is called to delete an STA context at hardware
2662 * whenever a STA is disassociated
2663 *
2664 ***LOGIC:
2665 *
2666 ***ASSUMPTIONS:
2667 * NA
2668 *
2669 ***NOTE:
2670 * NA
2671 *
2672 * @param pMac - Pointer to Global MAC structure
2673 * @param pStaDs - Pointer to the STA datastructure created by
2674 * LIM and maintained by DPH
2675 * @param fRespReqd - flag to indicate whether the delete is synchronous (true)
2676 * or not (false)
2677 * @return retCode - Indicates success or failure return code
2678 */
2679
2680tSirRetStatus
2681lim_del_sta(tpAniSirGlobal pMac,
2682 tpDphHashNode pStaDs, bool fRespReqd, tpPESession psessionEntry)
2683{
2684 tpDeleteStaParams pDelStaParams = NULL;
2685 tSirMsgQ msgQ;
2686 tSirRetStatus retCode = eSIR_SUCCESS;
2687
2688 pDelStaParams = cdf_mem_malloc(sizeof(tDeleteStaParams));
2689 if (NULL == pDelStaParams) {
2690 lim_log(pMac, LOGP,
2691 FL("Unable to allocate memory during ADD_STA"));
2692 return eSIR_MEM_ALLOC_FAILED;
2693 }
2694
2695 cdf_mem_set((uint8_t *) pDelStaParams, sizeof(tDeleteStaParams), 0);
2696
2697 /* */
2698 /* DPH contains the STA index only for "peer" STA entries. */
2699 /* LIM global contains "self" STA index */
2700 /* Thus, */
2701 /* if( STA role ) */
2702 /* get STA index from LIM global */
2703 /* else */
2704 /* get STA index from DPH */
2705 /* */
2706
2707#ifdef FEATURE_WLAN_TDLS
2708 if ((LIM_IS_STA_ROLE(psessionEntry) &&
2709 (pStaDs->staType != STA_ENTRY_TDLS_PEER)) ||
2710 LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
2711#else
2712 if (LIM_IS_STA_ROLE(psessionEntry) ||
2713 LIM_IS_BT_AMP_STA_ROLE(psessionEntry))
2714#endif
2715 pDelStaParams->staIdx = psessionEntry->staId;
2716
2717 else
2718 pDelStaParams->staIdx = pStaDs->staIndex;
2719
2720 pDelStaParams->assocId = pStaDs->assocId;
2721 pStaDs->valid = 0;
2722
2723 if (!fRespReqd)
2724 pDelStaParams->respReqd = 0;
2725 else {
2726 /* when lim_del_sta is called from processSmeAssocCnf then mlmState is already set properly. */
2727 if (eLIM_MLM_WT_ASSOC_DEL_STA_RSP_STATE !=
2728 GET_LIM_STA_CONTEXT_MLM_STATE(pStaDs)) {
2729 MTRACE(mac_trace
2730 (pMac, TRACE_CODE_MLM_STATE,
2731 psessionEntry->peSessionId,
2732 eLIM_MLM_WT_DEL_STA_RSP_STATE));
2733 SET_LIM_STA_CONTEXT_MLM_STATE(pStaDs,
2734 eLIM_MLM_WT_DEL_STA_RSP_STATE);
2735 }
2736 if (LIM_IS_STA_ROLE(psessionEntry) ||
2737 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
2738 MTRACE(mac_trace
2739 (pMac, TRACE_CODE_MLM_STATE,
2740 psessionEntry->peSessionId,
2741 eLIM_MLM_WT_DEL_STA_RSP_STATE));
2742
2743 psessionEntry->limMlmState =
2744 eLIM_MLM_WT_DEL_STA_RSP_STATE;
2745
2746 }
2747 pDelStaParams->respReqd = 1;
2748 /* we need to defer the message until we get the response back from HAL. */
2749 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
2750 }
2751
2752 /* Update PE session ID */
2753 pDelStaParams->sessionId = psessionEntry->peSessionId;
2754 pDelStaParams->smesessionId = psessionEntry->smeSessionId;
2755
2756 pDelStaParams->staType = pStaDs->staType;
2757 cdf_mem_copy((uint8_t *) pDelStaParams->staMac,
2758 (uint8_t *) pStaDs->staAddr, sizeof(tSirMacAddr));
2759
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302760 pDelStaParams->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002761 msgQ.type = WMA_DELETE_STA_REQ;
2762 msgQ.reserved = 0;
2763 msgQ.bodyptr = pDelStaParams;
2764 msgQ.bodyval = 0;
2765
2766 lim_log(pMac, LOG1, FL("Sessionid %d :Sending SIR_HAL_DELETE_STA_REQ "
2767 "for STAID: %X and AssocID: %d MAC : "
2768 MAC_ADDRESS_STR), pDelStaParams->sessionId,
2769 pDelStaParams->staIdx, pDelStaParams->assocId,
2770 MAC_ADDR_ARRAY(pStaDs->staAddr));
2771
2772 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
2773 retCode = wma_post_ctrl_msg(pMac, &msgQ);
2774 if (eSIR_SUCCESS != retCode) {
2775 if (fRespReqd)
2776 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
2777 lim_log(pMac, LOGE,
2778 FL("Posting DELETE_STA_REQ to HAL failed, reason=%X"),
2779 retCode);
2780 cdf_mem_free(pDelStaParams);
2781 }
2782
2783 return retCode;
2784}
2785
2786#if defined WLAN_FEATURE_VOWIFI_11R
2787/**
2788 * lim_add_ft_sta_self()- function to add STA once we have connected with a
2789 * new AP
2790 * @mac_ctx: pointer to global mac structure
2791 * @assoc_id: association id for the station connection
2792 * @session_entry: pe session entr
2793 *
2794 * This function is called to add a STA once we have connected with a new
2795 * AP, that we have performed an FT to.
2796 *
2797 * The Add STA Response is created and now after the ADD Bss Is Successful
2798 * we add the self sta. We update with the association id from the reassoc
2799 * response from the AP.
2800 *
2801 * Return: eSIR_SUCCESS on success else eSirRetStatus failure codes
2802 */
2803tSirRetStatus lim_add_ft_sta_self(tpAniSirGlobal mac_ctx, uint16_t assoc_id,
2804 tpPESession session_entry)
2805{
2806 tpAddStaParams add_sta_params = NULL;
2807 tSirRetStatus ret_code = eSIR_SUCCESS;
2808 tSirMsgQ msg_q;
2809
2810 add_sta_params = session_entry->ftPEContext.pAddStaReq;
2811 add_sta_params->assocId = assoc_id;
2812 add_sta_params->smesessionId = session_entry->smeSessionId;
2813
2814 msg_q.type = WMA_ADD_STA_REQ;
2815 msg_q.reserved = 0;
2816 msg_q.bodyptr = add_sta_params;
2817 msg_q.bodyval = 0;
2818
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302819 QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002820 "Sending WMA_ADD_STA_REQ (aid %d)",
2821 add_sta_params->assocId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002822 MTRACE(mac_trace_msg_tx(mac_ctx, session_entry->peSessionId,
2823 msg_q.type));
2824
2825 session_entry->limPrevMlmState = session_entry->limMlmState;
2826 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
2827 session_entry->peSessionId, eLIM_MLM_WT_ADD_STA_RSP_STATE));
2828 session_entry->limMlmState = eLIM_MLM_WT_ADD_STA_RSP_STATE;
2829 ret_code = wma_post_ctrl_msg(mac_ctx, &msg_q);
2830 if (eSIR_SUCCESS != ret_code) {
2831 lim_log(mac_ctx, LOGE,
2832 FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
2833 ret_code);
2834 cdf_mem_free(add_sta_params);
2835 }
2836
2837 session_entry->ftPEContext.pAddStaReq = NULL;
2838 return ret_code;
2839}
2840#endif /* WLAN_FEATURE_VOWIFI_11R */
2841
2842/**
2843 * lim_add_sta_self()
2844 *
2845 ***FUNCTION:
2846 * This function is called to add an STA context at hardware
2847 * whenever a STA is (Re) Associated.
2848 *
2849 ***LOGIC:
2850 *
2851 ***ASSUMPTIONS:
2852 * NA
2853 *
2854 ***NOTE:
2855 * NA
2856 *
2857 * @param pMac - Pointer to Global MAC structure
2858 * @param pStaDs - Pointer to the STA datastructure created by
2859 * LIM and maintained by DPH
2860 * @return retCode - Indicates success or failure return code
2861 */
2862
2863tSirRetStatus
2864lim_add_sta_self(tpAniSirGlobal pMac, uint16_t staIdx, uint8_t updateSta,
2865 tpPESession psessionEntry)
2866{
2867 tpAddStaParams pAddStaParams = NULL;
2868 tSirMsgQ msgQ;
2869 tSirRetStatus retCode = eSIR_SUCCESS;
2870 tSirMacAddr staMac;
2871 uint32_t listenInterval = WNI_CFG_LISTEN_INTERVAL_STADEF;
2872 uint32_t shortGi20MhzSupport;
2873 uint32_t shortGi40MhzSupport;
2874 uint32_t ampduLenExponent = 0;
2875 /*This self Sta dot 11 mode comes from the cfg and the expectation here is
2876 * that cfg carries the systemwide capability that device under
2877 * consideration can support. This capability gets plumbed into the cfg
2878 * cache at system initialization time via the .dat and .ini file override
2879 * mechanisms and will not change. If it does change, it is the
2880 * responsibility of SME to evict the selfSta and reissue a new AddStaSelf
2881 * command.*/
2882 uint32_t selfStaDot11Mode = 0, selfTxWidth = 0;
2883 uint32_t val;
2884 wlan_cfg_get_int(pMac, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
2885 lim_log(pMac, LOG1, FL("cfgDot11Mode %d"), (int)selfStaDot11Mode);
2886 wlan_cfg_get_int(pMac, WNI_CFG_HT_CAP_INFO_SUPPORTED_CHAN_WIDTH_SET,
2887 &selfTxWidth);
2888 lim_log(pMac, LOG1, FL("SGI 20 %d"), (int)selfTxWidth);
2889 lim_log(pMac, LOG1, FL("Roam Channel Bonding Mode %d"),
2890 (int)pMac->roam.configParam.uCfgDot11Mode);
2891
2892 sir_copy_mac_addr(staMac, psessionEntry->selfMacAddr);
2893 lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ": "), MAC_ADDR_ARRAY(staMac));
2894 pAddStaParams = cdf_mem_malloc(sizeof(tAddStaParams));
2895 if (NULL == pAddStaParams) {
2896 lim_log(pMac, LOGP,
2897 FL("Unable to allocate memory during ADD_STA"));
2898 return eSIR_MEM_ALLOC_FAILED;
2899 }
2900 cdf_mem_set((uint8_t *) pAddStaParams, sizeof(tAddStaParams), 0);
2901
2902 /* / Add STA context at MAC HW (BMU, RHP & TFP) */
2903 cdf_mem_copy((uint8_t *) pAddStaParams->staMac,
2904 (uint8_t *) staMac, sizeof(tSirMacAddr));
2905
2906 cdf_mem_copy((uint8_t *) pAddStaParams->bssId,
2907 psessionEntry->bssId, sizeof(tSirMacAddr));
2908
2909 pAddStaParams->assocId = psessionEntry->limAID;
2910 pAddStaParams->staType = STA_ENTRY_SELF;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302911 pAddStaParams->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002912 pAddStaParams->respReqd = 1;
2913
2914 /* Update PE session ID */
2915 pAddStaParams->sessionId = psessionEntry->peSessionId;
2916
2917 /* Update SME session ID */
2918 pAddStaParams->smesessionId = psessionEntry->smeSessionId;
2919
2920 pAddStaParams->maxTxPower = psessionEntry->maxTxPower;
2921
2922 /* This will indicate HAL to "allocate" a new STA index */
2923 pAddStaParams->staIdx = staIdx;
2924 pAddStaParams->updateSta = updateSta;
2925
2926 if (wlan_cfg_get_int(pMac, WNI_CFG_SHORT_PREAMBLE, &val) !=
2927 eSIR_SUCCESS) {
2928 lim_log(pMac, LOGE, FL(
2929 "Couldn't get SHORT_PREAMBLE, set default"));
2930 pAddStaParams->shortPreambleSupported = 1;
2931 } else {
2932 pAddStaParams->shortPreambleSupported = val;
2933 }
2934
2935#ifdef WLAN_FEATURE_11AC
2936 lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
2937 psessionEntry, NULL);
2938#else
2939 lim_populate_own_rate_set(pMac, &pAddStaParams->supportedRates, NULL, false,
2940 psessionEntry);
2941#endif
2942 if (IS_DOT11_MODE_HT(selfStaDot11Mode)) {
2943 pAddStaParams->htCapable = true;
2944#ifdef DISABLE_GF_FOR_INTEROP
2945 if ((psessionEntry->pLimJoinReq != NULL)
2946 && (!psessionEntry->pLimJoinReq->bssDescription.
2947 aniIndicator)) {
2948 lim_log(pMac, LOGE,
2949 FL
2950 (" Turning off Greenfield, when adding self entry"));
2951 pAddStaParams->greenFieldCapable =
2952 WNI_CFG_GREENFIELD_CAPABILITY_DISABLE;
2953 } else
2954#endif
2955 {
2956 pAddStaParams->greenFieldCapable =
2957 lim_get_ht_capability(pMac, eHT_GREENFIELD,
2958 psessionEntry);
2959 pAddStaParams->ch_width =
2960 pMac->roam.configParam.channelBondingMode5GHz;
2961 pAddStaParams->mimoPS =
2962 lim_get_ht_capability(pMac, eHT_MIMO_POWER_SAVE,
2963 psessionEntry);
2964 pAddStaParams->rifsMode =
2965 lim_get_ht_capability(pMac, eHT_RIFS_MODE,
2966 psessionEntry);
2967 pAddStaParams->lsigTxopProtection =
2968 lim_get_ht_capability(pMac, eHT_LSIG_TXOP_PROTECTION,
2969 psessionEntry);
2970 pAddStaParams->maxAmpduDensity =
2971 lim_get_ht_capability(pMac, eHT_MPDU_DENSITY,
2972 psessionEntry);
2973 pAddStaParams->maxAmpduSize =
2974 lim_get_ht_capability(pMac, eHT_MAX_RX_AMPDU_FACTOR,
2975 psessionEntry);
2976 pAddStaParams->maxAmsduSize =
2977 lim_get_ht_capability(pMac, eHT_MAX_AMSDU_LENGTH,
2978 psessionEntry);
2979 pAddStaParams->fDsssCckMode40Mhz =
2980 lim_get_ht_capability(pMac, eHT_DSSS_CCK_MODE_40MHZ,
2981 psessionEntry);
2982 /*
2983 * We will read the gShortGI20Mhz from ini file, and if it is set
2984 * to 1 then we will tell Peer that we support 40Mhz short GI
2985 */
2986 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
2987 (pMac, WNI_CFG_SHORT_GI_20MHZ,
2988 &shortGi20MhzSupport))) {
2989 if (true == shortGi20MhzSupport) {
2990 pAddStaParams->fShortGI20Mhz =
2991 WNI_CFG_SHORT_GI_20MHZ_STAMAX;
2992 } else {
2993 pAddStaParams->fShortGI20Mhz = false;
2994 }
2995 } else {
2996 PELOGE(lim_log
2997 (pMac, LOGE,
2998 FL("could not retrieve shortGI 20Mhz"
2999 "CFG,setting value to default"));
3000 )
3001 pAddStaParams->fShortGI20Mhz =
3002 WNI_CFG_SHORT_GI_20MHZ_STADEF;
3003 }
3004
3005 /*
3006 * We will read the gShortGI40Mhz from ini file, and if it is set
3007 * to 1 then we will tell Peer that we support 40Mhz short GI
3008 */
3009 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
3010 (pMac, WNI_CFG_SHORT_GI_40MHZ,
3011 &shortGi40MhzSupport))) {
3012 if (true == shortGi40MhzSupport) {
3013 pAddStaParams->fShortGI40Mhz =
3014 WNI_CFG_SHORT_GI_40MHZ_STAMAX;
3015 } else {
3016 pAddStaParams->fShortGI40Mhz = false;
3017 }
3018 } else {
3019 PELOGE(lim_log
3020 (pMac, LOGE,
3021 FL("could not retrieve shortGI 40Mhz"
3022 "CFG,setting value to default"));
3023 )
3024 pAddStaParams->fShortGI40Mhz =
3025 WNI_CFG_SHORT_GI_40MHZ_STADEF;
3026 }
3027 lim_log(pMac, LOG2,
3028 FL(" greenFieldCapable: %d maxAmpduDensity = %d "
3029 "maxAmpduSize = %d"),
3030 pAddStaParams->greenFieldCapable,
3031 pAddStaParams->maxAmpduDensity,
3032 pAddStaParams->maxAmpduSize);
3033
3034 lim_log(pMac, LOG2,
3035 FL("fDsssCckMode40Mhz: %d fShortGI20Mhz: %d "
3036 "fShortGI40Mhz: %d lsigTxopProtection: %d"),
3037 pAddStaParams->fDsssCckMode40Mhz,
3038 pAddStaParams->fShortGI20Mhz,
3039 pAddStaParams->fShortGI40Mhz,
3040 pAddStaParams->lsigTxopProtection);
3041
3042 lim_log(pMac, LOG2,
3043 FL("maxAmsduSize: %d txChannelWidth: %d mimoPS: %d rifsMode %d"),
3044 pAddStaParams->maxAmsduSize,
3045 pAddStaParams->ch_width,
3046 pAddStaParams->mimoPS, pAddStaParams->rifsMode);
3047 }
3048 }
3049#ifdef WLAN_FEATURE_11AC
3050 pAddStaParams->vhtCapable = IS_DOT11_MODE_VHT(selfStaDot11Mode);
3051 if (pAddStaParams->vhtCapable) {
3052 pAddStaParams->ch_width =
3053 psessionEntry->ch_width;
3054 lim_log(pMac, LOG1, FL("VHT WIDTH SET %d"),
3055 pAddStaParams->ch_width);
3056 }
3057 pAddStaParams->vhtTxBFCapable = psessionEntry->txBFIniFeatureEnabled;
3058 pAddStaParams->enable_su_tx_bformer =
3059 psessionEntry->enable_su_tx_bformer;
3060 lim_log(pMac, LOG2, FL("vhtCapable: %d vhtTxBFCapable %d, su_bfer %d"),
3061 pAddStaParams->vhtCapable, pAddStaParams->vhtTxBFCapable,
3062 pAddStaParams->enable_su_tx_bformer);
3063
3064 /* In 11ac mode, the hardware is capable of supporting 128K AMPDU size */
3065 if (IS_DOT11_MODE_VHT(selfStaDot11Mode)) {
3066 if (wlan_cfg_get_int
3067 (pMac, WNI_CFG_VHT_AMPDU_LEN_EXPONENT, &ampduLenExponent)
3068 != eSIR_SUCCESS) {
3069 lim_log(pMac, LOGP,
3070 FL
3071 ("Couldn't get WNI_CFG_VHT_AMPDU_LEN_EXPONENT"));
3072 }
3073 pAddStaParams->maxAmpduSize = (uint8_t) ampduLenExponent;
3074 }
3075 pAddStaParams->vhtTxMUBformeeCapable = psessionEntry->txMuBformee;
3076 pAddStaParams->enableVhtpAid = psessionEntry->enableVhtpAid;
3077#endif
3078 pAddStaParams->enableAmpduPs = psessionEntry->enableAmpduPs;
3079 pAddStaParams->enableHtSmps = psessionEntry->enableHtSmps;
3080 pAddStaParams->htSmpsconfig = psessionEntry->htSmpsvalue;
3081
3082 /* For Self STA get the LDPC capability from session i.e config.ini */
3083 pAddStaParams->htLdpcCapable =
3084 (psessionEntry->txLdpcIniFeatureEnabled & 0x01);
3085 pAddStaParams->vhtLdpcCapable =
3086 ((psessionEntry->txLdpcIniFeatureEnabled >> 1) & 0x01);
3087
3088 if (wlan_cfg_get_int(pMac, WNI_CFG_LISTEN_INTERVAL, &listenInterval) !=
3089 eSIR_SUCCESS)
3090 lim_log(pMac, LOGP, FL("Couldn't get LISTEN_INTERVAL"));
3091 pAddStaParams->listenInterval = (uint16_t) listenInterval;
3092
Anurag Chouhan6d760662016-02-20 16:05:43 +05303093 if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003094 pAddStaParams->p2pCapableSta = 1;
3095 }
3096
3097 pAddStaParams->supportedRates.opRateMode =
3098 lim_get_sta_rate_mode((uint8_t) selfStaDot11Mode);
3099
3100 lim_log(pMac, LOG2, FL(" StaIdx: %d updateSta = %d htcapable = %d "),
3101 pAddStaParams->staIdx, pAddStaParams->updateSta,
3102 pAddStaParams->htCapable);
3103
3104 lim_log(pMac, LOG2, FL("htLdpcCapable: %d vhtLdpcCapable: %d "
3105 "p2pCapableSta: %d"),
3106 pAddStaParams->htLdpcCapable, pAddStaParams->vhtLdpcCapable,
3107 pAddStaParams->p2pCapableSta);
3108
3109 if (psessionEntry->isNonRoamReassoc) {
3110 pAddStaParams->nonRoamReassoc = 1;
3111 psessionEntry->isNonRoamReassoc = 0;
3112 }
3113 lim_log(pMac, LOG2, FL("sessionid: %d Assoc ID: %d listenInterval = %d "
3114 "shortPreambleSupported: %d"),
3115 psessionEntry->smeSessionId, pAddStaParams->assocId,
3116 pAddStaParams->listenInterval,
3117 pAddStaParams->shortPreambleSupported);
3118
3119 msgQ.type = WMA_ADD_STA_REQ;
3120 msgQ.reserved = 0;
3121 msgQ.bodyptr = pAddStaParams;
3122 msgQ.bodyval = 0;
3123
3124 lim_log(pMac, LOG1, FL(MAC_ADDRESS_STR ":Sessionid %d : "
3125 "Sending WMA_ADD_STA_REQ. (aid %d)"),
3126 MAC_ADDR_ARRAY(pAddStaParams->staMac),
3127 pAddStaParams->sessionId, pAddStaParams->assocId);
3128 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
3129
3130 retCode = wma_post_ctrl_msg(pMac, &msgQ);
3131 if (eSIR_SUCCESS != retCode) {
3132 lim_log(pMac, LOGE,
3133 FL("Posting WMA_ADD_STA_REQ to HAL failed, reason=%X"),
3134 retCode);
3135 cdf_mem_free(pAddStaParams);
3136 }
3137 return retCode;
3138}
3139
3140/**
3141 * limTeardownInfraBSS()
3142 *
3143 ***FUNCTION:
3144 * This function is called by various LIM functions to teardown
3145 * an established Infrastructure BSS
3146 *
3147 ***LOGIC:
3148 *
3149 ***ASSUMPTIONS:
3150 *
3151 ***NOTE:
3152 *
3153 * @param pMac - Pointer to Global MAC structure
3154 * @return None
3155 */
3156
3157void lim_teardown_infra_bss(tpAniSirGlobal pMac, tpPESession psessionEntry)
3158{
3159 tSirMacAddr bcAddr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
3160
3161 /**
3162 * Send Broadcast Disassociate frame with
3163 * 'leaving BSS' reason.
3164 */
3165 lim_send_disassoc_mgmt_frame(pMac,
3166 eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
3167 bcAddr, psessionEntry, false);
3168} /*** end lim_teardown_infra_bss() ***/
3169
3170/**
3171 * lim_handle_cnf_wait_timeout()
3172 *
3173 ***FUNCTION:
3174 * This function is called by limProcessMessageQueue to handle
3175 * various confirmation failure cases.
3176 *
3177 ***LOGIC:
3178 *
3179 ***ASSUMPTIONS:
3180 *
3181 ***NOTE:
3182 *
3183 * @param pMac - Pointer to Global MAC structure
3184 * @param pStaDs - Pointer to a sta descriptor
3185 * @return None
3186 */
3187
3188void lim_handle_cnf_wait_timeout(tpAniSirGlobal pMac, uint16_t staId)
3189{
3190 tpDphHashNode pStaDs;
3191 tpPESession psessionEntry = NULL;
3192
3193 psessionEntry = pe_find_session_by_session_id(pMac,
3194 pMac->lim.limTimers.gpLimCnfWaitTimer[staId].sessionId);
3195 if (psessionEntry == NULL) {
3196 lim_log(pMac, LOGP,
3197 FL("Session Does not exist for given sessionID"));
3198 return;
3199 }
3200 pStaDs = dph_get_hash_entry(pMac, staId, &psessionEntry->dph.dphHashTable);
3201
3202 if (pStaDs == NULL) {
3203 PELOGW(lim_log
3204 (pMac, LOGW,
3205 FL("No STA context in SIR_LIM_CNF_WAIT_TIMEOUT."));
3206 )
3207 return;
3208 }
3209
3210 switch (pStaDs->mlmStaContext.mlmState) {
3211 case eLIM_MLM_WT_ASSOC_CNF_STATE:
3212 PELOGW(lim_log
3213 (pMac, LOGW,
3214 FL
3215 ("Did not receive Assoc Cnf in eLIM_MLM_WT_ASSOC_CNF_STATE sta Assoc id %d"),
3216 pStaDs->assocId);
3217 )
3218 lim_print_mac_addr(pMac, pStaDs->staAddr, LOGW);
3219
3220 if (LIM_IS_AP_ROLE(psessionEntry) ||
3221 LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
3222 lim_reject_association(pMac, pStaDs->staAddr,
3223 pStaDs->mlmStaContext.subType,
3224 true,
3225 pStaDs->mlmStaContext.authType,
3226 pStaDs->assocId, true,
3227 (tSirResultCodes)
3228 eSIR_MAC_UNSPEC_FAILURE_STATUS,
3229 psessionEntry);
3230 }
3231 break;
3232
3233 default:
3234 lim_log(pMac, LOGW, FL("Received CNF_WAIT_TIMEOUT in state %d"),
3235 pStaDs->mlmStaContext.mlmState);
3236 }
3237}
3238
3239/**
3240 * lim_delete_dph_hash_entry()- function to delete dph hash entry
3241 * @mac_ctx: pointer to global mac structure
3242 * @sta_addr: peer station address
3243 * @sta_id: id assigned to peer station
3244 * @session_entry: pe session entry
3245 *
3246 * This function is called whenever we need to delete
3247 * the dph hash entry
3248 *
3249 * Return: none
3250 */
3251
3252void
3253lim_delete_dph_hash_entry(tpAniSirGlobal mac_ctx, tSirMacAddr sta_addr,
3254 uint16_t sta_id, tpPESession session_entry)
3255{
3256 uint16_t aid;
3257 tpDphHashNode sta_ds;
3258 tUpdateBeaconParams beacon_params;
3259
3260 cdf_mem_zero(&beacon_params, sizeof(tUpdateBeaconParams));
3261 beacon_params.paramChangeBitmap = 0;
3262 lim_deactivate_and_change_per_sta_id_timer(mac_ctx, eLIM_CNF_WAIT_TIMER,
3263 sta_id);
3264 if (NULL == session_entry) {
3265 lim_log(mac_ctx, LOGE, FL("NULL session_entry"));
3266 return;
3267 }
3268
3269 beacon_params.bssIdx = session_entry->bssIdx;
3270 sta_ds = dph_lookup_hash_entry(mac_ctx, sta_addr, &aid,
3271 &session_entry->dph.dphHashTable);
3272
3273 if (sta_ds == NULL) {
3274 lim_log(mac_ctx, LOGE, FL("sta_ds is NULL"));
3275 return;
3276 }
3277
3278 lim_log(mac_ctx, LOGW, FL("Deleting DPH Hash entry for STAID: %X"),
3279 sta_id);
3280 /*
3281 * update the station count and perform associated actions
3282 * do this before deleting the dph hash entry
3283 */
3284 lim_util_count_sta_del(mac_ctx, sta_ds, session_entry);
3285
3286 if (LIM_IS_AP_ROLE(session_entry) || LIM_IS_IBSS_ROLE(session_entry)) {
3287 if (LIM_IS_AP_ROLE(session_entry)) {
3288 if (session_entry->gLimProtectionControl !=
3289 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
3290 lim_decide_ap_protection_on_delete(mac_ctx,
3291 sta_ds, &beacon_params, session_entry);
3292 }
3293
3294 if (LIM_IS_IBSS_ROLE(session_entry))
3295 lim_ibss_decide_protection_on_delete(mac_ctx, sta_ds,
3296 &beacon_params, session_entry);
3297
3298 lim_decide_short_preamble(mac_ctx, sta_ds, &beacon_params,
3299 session_entry);
3300 lim_decide_short_slot(mac_ctx, sta_ds, &beacon_params,
3301 session_entry);
3302
3303 /* Send message to HAL about beacon parameter change. */
3304 lim_log(mac_ctx, LOGW, FL("param bitmap = %d "),
3305 beacon_params.paramChangeBitmap);
3306 if (beacon_params.paramChangeBitmap &&
3307 (false ==
3308 mac_ctx->sap.SapDfsInfo.is_dfs_cac_timer_running)) {
3309 sch_set_fixed_beacon_fields(mac_ctx, session_entry);
3310 lim_send_beacon_params(mac_ctx, &beacon_params,
3311 session_entry);
3312 }
3313#ifdef WLAN_FEATURE_11W
3314 tx_timer_delete(&sta_ds->pmfSaQueryTimer);
3315#endif
3316 }
3317
3318 if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id,
3319 &session_entry->dph.dphHashTable) != eSIR_SUCCESS)
3320 lim_log(mac_ctx, LOGP, FL("error deleting hash entry"));
3321}
3322
3323/**
3324 * lim_check_and_announce_join_success()- function to check if the received
3325 * Beacon/Probe Response is from the BSS that we're attempting to join.
3326 * @mac: pointer to global mac structure
3327 * @beacon_probe_rsp: pointer to reveived beacon/probe response frame
3328 * @header: pointer to received management frame header
3329 * @session_entry: pe session entry
3330 *
3331 * This function is called upon receiving Beacon/Probe Response
3332 * frame in WT_JOIN_BEACON_STATE to check if the received
3333 * Beacon/Probe Response is from the BSS that we're attempting
3334 * to join.
3335 * If the Beacon/Probe Response is indeed from the BSS we're
3336 * attempting to join, join success is sent to SME.
3337 *
3338 * Return: none
3339 */
3340
3341void
3342lim_check_and_announce_join_success(tpAniSirGlobal mac_ctx,
3343 tSirProbeRespBeacon *beacon_probe_rsp, tpSirMacMgmtHdr header,
3344 tpPESession session_entry)
3345{
3346 tSirMacSSid current_ssid;
3347 tLimMlmJoinCnf mlm_join_cnf;
3348 uint32_t val = 0;
3349 uint32_t *noa_duration_from_beacon = NULL;
3350 uint32_t *noa2_duration_from_beacon = NULL;
3351 uint32_t noa;
3352 uint32_t total_num_noa_desc = 0;
Kiran Kumar Lokere92d11bf2015-12-15 16:51:18 -08003353 uint32_t selfStaDot11Mode = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003354
3355 cdf_mem_copy(current_ssid.ssId,
3356 session_entry->ssId.ssId, session_entry->ssId.length);
3357
3358 current_ssid.length = (uint8_t) session_entry->ssId.length;
3359
3360 /*
3361 * Check for SSID only in probe response. Beacons may not carry
3362 * SSID information in hidden SSID case
3363 */
3364 if (((SIR_MAC_MGMT_FRAME == header->fc.type) &&
3365 (SIR_MAC_MGMT_PROBE_RSP == header->fc.subType)) &&
3366 current_ssid.length &&
3367 (!cdf_mem_compare((uint8_t *) &beacon_probe_rsp->ssId,
3368 (uint8_t *) &current_ssid,
3369 (uint8_t) (1 + current_ssid.length)))) {
3370 /*
3371 * Received SSID does not match with the one we've.
3372 * Ignore received Beacon frame
3373 */
3374 lim_log(mac_ctx, LOG1,
3375 FL("SSID received in Beacon does not match"));
3376#ifdef WLAN_DEBUG
3377 mac_ctx->lim.gLimBcnSSIDMismatchCnt++;
3378#endif
3379 return;
3380 }
3381
3382 if (!(LIM_IS_BT_AMP_STA_ROLE(session_entry) ||
3383 LIM_IS_STA_ROLE(session_entry)))
3384 return;
3385
3386 lim_log(mac_ctx, LOG1,
3387 FL("Received Beacon/PR with matching BSSID:%pM PESessionID %d"),
3388 session_entry->bssId, session_entry->peSessionId);
3389
3390 /* Deactivate Join Failure timer */
3391 lim_deactivate_and_change_timer(mac_ctx, eLIM_JOIN_FAIL_TIMER);
3392 /* Deactivate Periodic Join timer */
3393 lim_deactivate_and_change_timer(mac_ctx,
3394 eLIM_PERIODIC_JOIN_PROBE_REQ_TIMER);
3395
Anurag Chouhan6d760662016-02-20 16:05:43 +05303396 if (QDF_P2P_CLIENT_MODE == session_entry->pePersona &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003397 beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.present) {
3398
3399 noa_duration_from_beacon = (uint32_t *)
3400 (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc + 1);
3401
3402 if (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.num_NoADesc)
3403 total_num_noa_desc =
3404 beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.
3405 num_NoADesc / SIZE_OF_NOA_DESCRIPTOR;
3406
3407 noa = *noa_duration_from_beacon;
3408
3409 if (total_num_noa_desc > 1) {
3410 noa2_duration_from_beacon = (uint32_t *)
3411 (beacon_probe_rsp->P2PProbeRes.NoticeOfAbsence.NoADesc +
3412 SIZE_OF_NOA_DESCRIPTOR + 1);
3413 noa += *noa2_duration_from_beacon;
3414 }
3415
3416 /*
3417 * If MAX Noa exceeds 3 secs we will consider only 3 secs to
3418 * avoid arbitary values in noa duration field
3419 */
3420 noa = noa > MAX_NOA_PERIOD_IN_MICROSECS ?
3421 MAX_NOA_PERIOD_IN_MICROSECS : noa;
3422 noa = noa / 1000; /* Convert to ms */
3423
3424 if (wlan_cfg_get_int(mac_ctx,
3425 WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT, &val) ==
3426 eSIR_SUCCESS) {
3427 session_entry->defaultAuthFailureTimeout = val;
3428 cfg_set_int(mac_ctx,
3429 WNI_CFG_AUTHENTICATE_FAILURE_TIMEOUT,
3430 val + noa);
3431 }
3432 } else {
3433 session_entry->defaultAuthFailureTimeout = 0;
3434 }
3435
3436 /* Update Beacon Interval at CFG database */
3437
3438 if (beacon_probe_rsp->HTCaps.present)
3439 lim_update_sta_run_time_ht_capability(mac_ctx,
3440 &beacon_probe_rsp->HTCaps);
3441 if (beacon_probe_rsp->HTInfo.present)
3442 lim_update_sta_run_time_ht_info(mac_ctx,
3443 &beacon_probe_rsp->HTInfo, session_entry);
3444 session_entry->limMlmState = eLIM_MLM_JOINED_STATE;
3445 MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE,
3446 session_entry->peSessionId, eLIM_MLM_JOINED_STATE));
3447
3448 /*
3449 * update the capability info based on recently received beacon/probe
3450 * response frame
3451 */
3452 session_entry->limCurrentBssCaps =
3453 lim_get_u16((uint8_t *)&beacon_probe_rsp->capabilityInfo);
3454
3455 /*
3456 * Announce join success by sending
3457 * Join confirm to SME.
3458 */
3459 mlm_join_cnf.resultCode = eSIR_SME_SUCCESS;
3460 mlm_join_cnf.protStatusCode = eSIR_MAC_SUCCESS_STATUS;
3461 /* Update PE sessionId */
3462 mlm_join_cnf.sessionId = session_entry->peSessionId;
3463 lim_post_sme_message(mac_ctx, LIM_MLM_JOIN_CNF,
3464 (uint32_t *) &mlm_join_cnf);
3465
Kiran Kumar Lokere92d11bf2015-12-15 16:51:18 -08003466 wlan_cfg_get_int(mac_ctx, WNI_CFG_DOT11_MODE, &selfStaDot11Mode);
3467
3468 if ((IS_DOT11_MODE_VHT(selfStaDot11Mode)) &&
3469 beacon_probe_rsp->vendor2_ie.VHTCaps.present) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003470 session_entry->is_vendor_specific_vhtcaps = true;
3471 session_entry->vendor_specific_vht_ie_type =
3472 beacon_probe_rsp->vendor2_ie.type;
3473 session_entry->vendor_specific_vht_ie_sub_type =
3474 beacon_probe_rsp->vendor2_ie.sub_type;
3475 lim_log(mac_ctx, LOG1, FL(
3476 "VHT caps are present in vendor specific IE"));
3477 }
3478}
3479
3480/**
3481 * lim_extract_ap_capabilities()
3482 *
3483 ***FUNCTION:
3484 * This function is called to extract all of the AP's capabilities
3485 * from the IEs received from it in Beacon/Probe Response frames
3486 *
3487 ***LOGIC:
3488 * This routine mimics the lim_extract_ap_capability() API. The difference here
3489 * is that this API returns the entire tSirProbeRespBeacon info as is. It is
3490 * left to the caller of this API to use this info as required
3491 *
3492 ***ASSUMPTIONS:
3493 * NA
3494 *
3495 ***NOTE:
3496 *
3497 * @param pMac Pointer to Global MAC structure
3498 * @param pIE Pointer to starting IE in Beacon/Probe Response
3499 * @param ieLen Length of all IEs combined
3500 * @param beaconStruct A pointer to tSirProbeRespBeacon that needs to be
3501 * populated
3502 * @return status A status reporting eSIR_SUCCESS or eSIR_FAILURE
3503 */
3504tSirRetStatus lim_extract_ap_capabilities(tpAniSirGlobal pMac,
3505 uint8_t *pIE,
3506 uint16_t ieLen,
3507 tpSirProbeRespBeacon beaconStruct)
3508{
3509 cdf_mem_set((uint8_t *) beaconStruct, sizeof(tSirProbeRespBeacon), 0);
3510
3511 PELOG3(lim_log(pMac, LOG3,
3512 FL
3513 ("In lim_extract_ap_capabilities: The IE's being received are:"));
3514 sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG3, pIE, ieLen);
3515 )
3516 /* Parse the Beacon IE's, Don't try to parse if we dont have anything in IE */
3517 if (ieLen > 0) {
3518 if (eSIR_SUCCESS !=
3519 sir_parse_beacon_ie(pMac, beaconStruct, pIE,
3520 (uint32_t) ieLen)) {
3521 lim_log(pMac, LOGE,
3522 FL("APCapExtract: Beacon parsing error!"));
3523 return eSIR_FAILURE;
3524 }
3525 }
3526
3527 return eSIR_SUCCESS;
3528}
3529
3530/**
3531 * lim_del_bss()
3532 *
3533 ***FUNCTION:
3534 * This function is called to delete BSS context at hardware
3535 * whenever a STA is disassociated
3536 *
3537 ***LOGIC:
3538 *
3539 ***ASSUMPTIONS:
3540 * NA
3541 *
3542 ***NOTE:
3543 * NA
3544 *
3545 * @param pMac - Pointer to Global MAC structure
3546 * @param pStaDs - Pointer to the STA datastructure created by
3547 * LIM and maintained by DPH
3548 * @return retCode - Indicates success or failure return code
3549 */
3550
3551tSirRetStatus
3552lim_del_bss(tpAniSirGlobal pMac, tpDphHashNode pStaDs, uint16_t bssIdx,
3553 tpPESession psessionEntry)
3554{
3555 tpDeleteBssParams pDelBssParams = NULL;
3556 tSirMsgQ msgQ;
3557 tSirRetStatus retCode = eSIR_SUCCESS;
3558
3559 pDelBssParams = cdf_mem_malloc(sizeof(tDeleteBssParams));
3560 if (NULL == pDelBssParams) {
3561 lim_log(pMac, LOGP,
3562 FL("Unable to allocate memory during ADD_BSS"));
3563 return eSIR_MEM_ALLOC_FAILED;
3564 }
3565 cdf_mem_set((uint8_t *) pDelBssParams, sizeof(tDeleteBssParams), 0);
3566
3567 pDelBssParams->sessionId = psessionEntry->peSessionId; /* update PE session Id */
3568
3569 /* DPH was storing the AssocID in staID field, */
3570 /* staID is actually assigned by HAL when AddSTA message is sent. */
3571 if (pStaDs != NULL) {
3572 pDelBssParams->bssIdx = pStaDs->bssId;
3573 pStaDs->valid = 0;
3574 pStaDs->mlmStaContext.mlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
3575 } else
3576 pDelBssParams->bssIdx = bssIdx;
3577 psessionEntry->limMlmState = eLIM_MLM_WT_DEL_BSS_RSP_STATE;
3578 MTRACE(mac_trace
3579 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
3580 eLIM_MLM_WT_DEL_BSS_RSP_STATE));
3581
3582 if ((psessionEntry->peSessionId ==
3583 pMac->lim.limTimers.gLimJoinFailureTimer.sessionId)
3584 && (true ==
3585 tx_timer_running(&pMac->lim.limTimers.gLimJoinFailureTimer))) {
3586 lim_deactivate_and_change_timer(pMac, eLIM_JOIN_FAIL_TIMER);
3587 }
3588
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303589 pDelBssParams->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003590 pDelBssParams->respReqd = 1;
3591 cdf_mem_copy(pDelBssParams->bssid, psessionEntry->bssId,
3592 sizeof(tSirMacAddr));
3593 pDelBssParams->smesessionId = psessionEntry->smeSessionId;
3594 PELOGW(lim_log
3595 (pMac, LOGW,
3596 FL("Sessionid %d : Sending HAL_DELETE_BSS_REQ "
3597 "for bss idx: %X BSSID:" MAC_ADDRESS_STR),
3598 pDelBssParams->sessionId, pDelBssParams->bssIdx,
3599 MAC_ADDR_ARRAY(psessionEntry->bssId));
3600 )
3601 /* we need to defer the message until we get the response back from HAL. */
3602 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
3603
3604 msgQ.type = WMA_DELETE_BSS_REQ;
3605 msgQ.reserved = 0;
3606 msgQ.bodyptr = pDelBssParams;
3607 msgQ.bodyval = 0;
3608
3609 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
3610
3611 retCode = wma_post_ctrl_msg(pMac, &msgQ);
3612 if (eSIR_SUCCESS != retCode) {
3613 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
3614 lim_log(pMac, LOGE,
3615 FL("Posting DELETE_BSS_REQ to HAL failed, reason=%X"),
3616 retCode);
3617 cdf_mem_free(pDelBssParams);
3618 }
3619
3620 return retCode;
3621}
3622
3623/**
3624 * lim_update_vhtcaps_assoc_resp : Update VHT caps in assoc response.
3625 * @mac_ctx Pointer to Global MAC structure
3626 * @pAddBssParams: parameters required for add bss params.
3627 * @vht_caps: VHT capabilities.
3628 * @psessionEntry : session entry.
3629 *
3630 * Return : void
3631 */
3632void lim_update_vhtcaps_assoc_resp(tpAniSirGlobal mac_ctx,
3633 tpAddBssParams pAddBssParams,
3634 tDot11fIEVHTCaps *vht_caps, tpPESession psessionEntry)
3635{
3636 pAddBssParams->staContext.vht_caps =
3637 ((vht_caps->maxMPDULen <<
3638 SIR_MAC_VHT_CAP_MAX_MPDU_LEN) |
3639 (vht_caps->supportedChannelWidthSet <<
3640 SIR_MAC_VHT_CAP_SUPP_CH_WIDTH_SET) |
3641 (vht_caps->ldpcCodingCap <<
3642 SIR_MAC_VHT_CAP_LDPC_CODING_CAP) |
3643 (vht_caps->shortGI80MHz <<
3644 SIR_MAC_VHT_CAP_SHORTGI_80MHZ) |
3645 (vht_caps->shortGI160and80plus80MHz <<
3646 SIR_MAC_VHT_CAP_SHORTGI_160_80_80MHZ) |
3647 (vht_caps->txSTBC <<
3648 SIR_MAC_VHT_CAP_TXSTBC) |
3649 (vht_caps->rxSTBC <<
3650 SIR_MAC_VHT_CAP_RXSTBC) |
3651 (vht_caps->suBeamFormerCap <<
3652 SIR_MAC_VHT_CAP_SU_BEAMFORMER_CAP) |
3653 (vht_caps->suBeamformeeCap <<
3654 SIR_MAC_VHT_CAP_SU_BEAMFORMEE_CAP) |
3655 (vht_caps->csnofBeamformerAntSup <<
3656 SIR_MAC_VHT_CAP_CSN_BEAMORMER_ANT_SUP) |
3657 (vht_caps->numSoundingDim <<
3658 SIR_MAC_VHT_CAP_NUM_SOUNDING_DIM) |
3659 (vht_caps->muBeamformerCap <<
3660 SIR_MAC_VHT_CAP_NUM_BEAM_FORMER_CAP) |
3661 (vht_caps->muBeamformeeCap <<
3662 SIR_MAC_VHT_CAP_NUM_BEAM_FORMEE_CAP) |
3663 (vht_caps->vhtTXOPPS <<
3664 SIR_MAC_VHT_CAP_TXOPPS) |
3665 (vht_caps->htcVHTCap <<
3666 SIR_MAC_VHT_CAP_HTC_CAP) |
3667 (vht_caps->maxAMPDULenExp <<
3668 SIR_MAC_VHT_CAP_MAX_AMDU_LEN_EXPO) |
3669 (vht_caps->vhtLinkAdaptCap <<
3670 SIR_MAC_VHT_CAP_LINK_ADAPT_CAP) |
3671 (vht_caps->rxAntPattern <<
3672 SIR_MAC_VHT_CAP_RX_ANTENNA_PATTERN) |
3673 (vht_caps->txAntPattern <<
3674 SIR_MAC_VHT_CAP_TX_ANTENNA_PATTERN) |
3675 (vht_caps->reserved1 <<
3676 SIR_MAC_VHT_CAP_RESERVED2));
3677
3678 pAddBssParams->staContext.maxAmpduSize =
3679 SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
3680 pAddBssParams->staContext.vht_caps);
3681
3682 lim_log(mac_ctx, LOG1,
3683 FL("Updating VHT caps in assoc Response"));
3684}
3685
3686/**
3687 * lim_update_vht_oper_assoc_resp : Update VHT Operations in assoc response.
3688 * @mac_ctx Pointer to Global MAC structure
3689 * @pAddBssParams: parameters required for add bss params.
3690 * @vht_oper: VHT Operations to update.
3691 * @psessionEntry : session entry.
3692 *
3693 * Return : void
3694 */
3695void lim_update_vht_oper_assoc_resp(tpAniSirGlobal mac_ctx,
3696 tpAddBssParams pAddBssParams,
3697 tDot11fIEVHTOperation *vht_oper, tpPESession psessionEntry)
3698{
3699 if (vht_oper->chanWidth &&
3700 psessionEntry->ch_width) {
3701 pAddBssParams->ch_width = vht_oper->chanWidth + 1;
3702
3703 pAddBssParams->ch_center_freq_seg0 =
3704 vht_oper->chanCenterFreqSeg1;
3705
3706 pAddBssParams->ch_center_freq_seg1 =
3707 vht_oper->chanCenterFreqSeg2;
3708 }
3709 lim_log(mac_ctx, LOG1,
3710 FL("Updating VHT Operation in assoc Response"));
3711}
3712
3713
3714/**
3715 * limSendAddBss()
3716 *
3717 ***FUNCTION:
3718 *
3719 ***LOGIC:
3720 * 1) LIM receives eWNI_SME_JOIN_REQ
3721 * 2) For a valid eWNI_SME_JOIN_REQ, LIM sends
3722 * SIR_HAL_ADD_BSS_REQ to HAL
3723 *
3724 ***ASSUMPTIONS:
3725 * JOIN REQ parameters are saved in pMac->lim.gLimMlmJoinReq
3726 * ADD BSS parameters can be obtained from two sources:
3727 * 1) pMac->lim.gLimMlmJoinReq
3728 * 2) beaconStruct, passed as paramter
3729 * So, if a reqd parameter is found in bssDescriptions
3730 * then it is given preference over beaconStruct
3731 *
3732 ***NOTE:
3733 *
3734 * @param pMac Pointer to Global MAC structure
3735 * pAssocRsp contains the structured assoc/reassoc Response got from AP
3736 * beaconstruct Has the ProbeRsp/Beacon structured details
3737 * bssDescription bssDescription passed to PE from the SME
3738 * @return None
3739 */
3740
3741tSirRetStatus lim_sta_send_add_bss(tpAniSirGlobal pMac, tpSirAssocRsp pAssocRsp,
3742 tpSchBeaconStruct pBeaconStruct,
3743 tpSirBssDescription bssDescription,
3744 uint8_t updateEntry, tpPESession psessionEntry)
3745{
3746 tSirMsgQ msgQ;
3747 tpAddBssParams pAddBssParams = NULL;
3748 uint32_t retCode;
3749 tpDphHashNode pStaDs = NULL;
3750 uint8_t chanWidthSupp = 0;
3751 uint32_t shortGi20MhzSupport;
3752 uint32_t shortGi40MhzSupport;
3753 uint32_t enableTxBF20MHz;
3754 tDot11fIEVHTCaps *vht_caps = NULL;
3755 tDot11fIEVHTOperation *vht_oper = NULL;
3756 tAddStaParams *sta_context;
3757
3758 /* Package SIR_HAL_ADD_BSS_REQ message parameters */
3759 pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams));
3760 if (NULL == pAddBssParams) {
3761 lim_log(pMac, LOGP,
3762 FL("Unable to allocate memory during ADD_BSS"));
3763 retCode = eSIR_MEM_ALLOC_FAILED;
3764 goto returnFailure;
3765 } else
3766 cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams),
3767 0);
3768
3769 cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
3770 sizeof(tSirMacAddr));
3771 /* Fill in tAddBssParams selfMacAddr */
3772 cdf_mem_copy(pAddBssParams->selfMacAddr,
3773 psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
3774
3775 lim_log(pMac, LOG1,
3776 FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
3777 psessionEntry->smeSessionId, updateEntry,
3778 GET_LIM_SYSTEM_ROLE(psessionEntry));
3779
3780 lim_log(pMac, LOG1, FL("BSSID: " MAC_ADDRESS_STR),
3781 MAC_ADDR_ARRAY(pAddBssParams->bssId));
3782
3783 if (psessionEntry->bssType == eSIR_BTAMP_AP_MODE) {
3784 pAddBssParams->bssType = eSIR_BTAMP_AP_MODE;
3785 } else {
3786 pAddBssParams->bssType = eSIR_INFRASTRUCTURE_MODE;
3787 }
3788
3789 pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
3790
3791 /* Update PE session ID */
3792 pAddBssParams->sessionId = psessionEntry->peSessionId;
3793
3794 pAddBssParams->beaconInterval = bssDescription->beaconInterval;
3795
3796 pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
3797 pAddBssParams->updateBss = updateEntry;
3798
3799 pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
3800 pAddBssParams->cfParamSet.cfpPeriod =
3801 pBeaconStruct->cfParamSet.cfpPeriod;
3802 pAddBssParams->cfParamSet.cfpMaxDuration =
3803 pBeaconStruct->cfParamSet.cfpMaxDuration;
3804 pAddBssParams->cfParamSet.cfpDurRemaining =
3805 pBeaconStruct->cfParamSet.cfpDurRemaining;
3806
3807 pAddBssParams->rateSet.numRates = pAssocRsp->supportedRates.numRates;
3808 cdf_mem_copy(pAddBssParams->rateSet.rate,
3809 pAssocRsp->supportedRates.rate,
3810 pAssocRsp->supportedRates.numRates);
3811
3812 if (IS_DOT11_MODE_11B(psessionEntry->dot11mode) &&
3813 bssDescription->nwType != eSIR_11B_NW_TYPE) {
3814 pAddBssParams->nwType = eSIR_11B_NW_TYPE;
3815 } else {
3816 pAddBssParams->nwType = bssDescription->nwType;
3817 }
3818
3819 pAddBssParams->shortSlotTimeSupported =
3820 (uint8_t) pAssocRsp->capabilityInfo.shortSlotTime;
3821 pAddBssParams->llaCoexist =
3822 (uint8_t) psessionEntry->beaconParams.llaCoexist;
3823 pAddBssParams->llbCoexist =
3824 (uint8_t) psessionEntry->beaconParams.llbCoexist;
3825 pAddBssParams->llgCoexist =
3826 (uint8_t) psessionEntry->beaconParams.llgCoexist;
3827 pAddBssParams->ht20Coexist =
3828 (uint8_t) psessionEntry->beaconParams.ht20Coexist;
3829
3830 lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
3831 "cfpCount: %d"), pAddBssParams->bssType,
3832 pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
3833 pAddBssParams->cfParamSet.cfpCount);
3834
3835 lim_log(pMac, LOG2,
3836 FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
3837 " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
3838 pAddBssParams->cfParamSet.cfpMaxDuration,
3839 pAddBssParams->cfParamSet.cfpDurRemaining,
3840 pAddBssParams->rateSet.numRates);
3841
3842 lim_log(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
3843 "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
3844 pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
3845 pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
3846 pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
3847
3848 pAddBssParams->dot11_mode = psessionEntry->dot11mode;
3849 lim_log(pMac, LOG2, FL("dot11_mode:%d"), pAddBssParams->dot11_mode);
3850
3851 /* Use the advertised capabilities from the received beacon/PR */
3852
3853 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
3854 && (pAssocRsp->HTCaps.present)) {
3855 pAddBssParams->htCapable = pAssocRsp->HTCaps.present;
3856 lim_log(pMac, LOG2, FL("htCapable: %d"),
3857 pAddBssParams->htCapable);
3858 if (pBeaconStruct->HTInfo.present) {
3859 pAddBssParams->htOperMode =
3860 (tSirMacHTOperatingMode) pAssocRsp->HTInfo.opMode;
3861 pAddBssParams->dualCTSProtection =
3862 (uint8_t) pAssocRsp->HTInfo.dualCTSProtection;
3863 chanWidthSupp =
3864 lim_get_ht_capability(pMac,
3865 eHT_SUPPORTED_CHANNEL_WIDTH_SET,
3866 psessionEntry);
3867 if ((pAssocRsp->HTCaps.supportedChannelWidthSet)
3868 && (chanWidthSupp)) {
3869 pAddBssParams->ch_width = (uint8_t)
3870 pAssocRsp->HTInfo.recommendedTxWidthSet;
3871 if (pAssocRsp->HTInfo.secondaryChannelOffset ==
3872 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
3873 pAddBssParams->ch_center_freq_seg0 =
3874 bssDescription->channelId + 2;
3875 else if (pAssocRsp->HTInfo.secondaryChannelOffset ==
3876 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
3877 pAddBssParams->ch_center_freq_seg0 =
3878 bssDescription->channelId - 2;
3879 } else {
3880 pAddBssParams->ch_width = CH_WIDTH_20MHZ;
3881 pAddBssParams->ch_center_freq_seg0 = 0;
3882 }
3883 pAddBssParams->llnNonGFCoexist =
3884 (uint8_t) pAssocRsp->HTInfo.nonGFDevicesPresent;
3885 pAddBssParams->fLsigTXOPProtectionFullSupport =
3886 (uint8_t) pAssocRsp->HTInfo.
3887 lsigTXOPProtectionFullSupport;
3888 pAddBssParams->fRIFSMode = pAssocRsp->HTInfo.rifsMode;
3889
3890 lim_log(pMac, LOGE,
3891 FL("htOperMode: %d dualCTSProtection: %d txChannelWidth: %d center_freq_0: %d "),
3892 pAddBssParams->htOperMode,
3893 pAddBssParams->dualCTSProtection,
3894 pAddBssParams->ch_width,
3895 pAddBssParams->ch_center_freq_seg0);
3896
3897 lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
3898 "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
3899 pAddBssParams->llnNonGFCoexist,
3900 pAddBssParams->fLsigTXOPProtectionFullSupport,
3901 pAddBssParams->fRIFSMode);
3902 }
3903 }
3904
3905 pAddBssParams->currentOperChannel = bssDescription->channelId;
3906 lim_log(pMac, LOGE, FL("currentOperChannel %d"),
3907 pAddBssParams->currentOperChannel);
3908 if (psessionEntry->vhtCapability && (pAssocRsp->VHTCaps.present)) {
3909 pAddBssParams->vhtCapable = pAssocRsp->VHTCaps.present;
3910 vht_caps = &pAssocRsp->VHTCaps;
3911 vht_oper = &pAssocRsp->VHTOperation;
3912 } else if (psessionEntry->vhtCapability &&
3913 pAssocRsp->vendor2_ie.VHTCaps.present){
3914 pAddBssParams->vhtCapable =
3915 pAssocRsp->vendor2_ie.VHTCaps.present;
3916 lim_log(pMac, LOG1,
3917 FL("VHT Caps and Operation are present in vendor Specfic IE"));
3918 vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
3919 vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
3920 } else {
3921 pAddBssParams->vhtCapable = 0;
3922 }
3923 if (pAddBssParams->vhtCapable) {
3924 if (vht_oper != NULL)
3925 lim_update_vht_oper_assoc_resp(pMac, pAddBssParams,
3926 vht_oper, psessionEntry);
3927 if (vht_caps != NULL)
3928 lim_update_vhtcaps_assoc_resp(pMac, pAddBssParams,
3929 vht_caps, psessionEntry);
3930 }
3931
3932 lim_log(pMac, LOGE, FL("vhtCapable %d TxChannelWidth %d center_freq_0 %d center_freq_1 %d"),
3933 pAddBssParams->vhtCapable, pAddBssParams->ch_width,
3934 pAddBssParams->ch_center_freq_seg0,
3935 pAddBssParams->ch_center_freq_seg1);
3936
3937 /*
3938 * Populate the STA-related parameters here
3939 * Note that the STA here refers to the AP
3940 * staType = PEER
3941 */
3942 sta_context = &pAddBssParams->staContext;
3943 /* Identifying AP as an STA */
3944 pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
3945
3946 cdf_mem_copy(pAddBssParams->staContext.bssId,
3947 bssDescription->bssId, sizeof(tSirMacAddr));
3948 pAddBssParams->staContext.listenInterval =
3949 bssDescription->beaconInterval;
3950
3951 /* Fill Assoc id from the dph table */
3952 pStaDs = dph_lookup_hash_entry(pMac, pAddBssParams->staContext.bssId,
3953 &pAddBssParams->staContext.assocId,
3954 &psessionEntry->dph.dphHashTable);
3955 if (pStaDs == NULL) {
3956 lim_log(pMac, LOGE, FL(
3957 "Couldn't get assoc id for " "MAC ADDR: "
3958 MAC_ADDRESS_STR),
3959 MAC_ADDR_ARRAY(
3960 pAddBssParams->staContext.staMac));
3961 return eSIR_FAILURE;
3962 }
3963
3964 pAddBssParams->staContext.uAPSD =
3965 psessionEntry->gUapsdPerAcBitmask;
3966
3967 pAddBssParams->staContext.maxSPLen = 0;
3968 pAddBssParams->staContext.shortPreambleSupported =
3969 (uint8_t) pAssocRsp->capabilityInfo.shortPreamble;
3970 pAddBssParams->staContext.updateSta = updateEntry;
3971
3972 lim_log(pMac, LOG2, FL("StaContext: " MAC_ADDRESS_STR
3973 " shortPreambleSupported: %d"),
3974 MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
3975 pAddBssParams->staContext.shortPreambleSupported);
3976
3977 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
3978 && pBeaconStruct->HTCaps.present) {
3979 pAddBssParams->staContext.us32MaxAmpduDuration = 0;
3980 pAddBssParams->staContext.htCapable = 1;
3981 pAddBssParams->staContext.greenFieldCapable =
3982 (uint8_t) pAssocRsp->HTCaps.greenField;
3983 pAddBssParams->staContext.lsigTxopProtection =
3984 (uint8_t) pAssocRsp->HTCaps.lsigTXOPProtection;
3985 lim_log(pMac, LOG2, FL(
3986 "StaCtx: htCap %d GFcap %d lsigTxopProtn %d"),
3987 pAddBssParams->staContext.htCapable,
3988 pAddBssParams->staContext.greenFieldCapable,
3989 pAddBssParams->staContext.lsigTxopProtection);
3990 if (psessionEntry->vhtCapability &&
3991 (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
3992 IS_BSS_VHT_CAPABLE(
3993 pBeaconStruct->vendor2_ie.VHTCaps))) {
3994 pAddBssParams->staContext.vhtCapable = 1;
3995 pAddBssParams->staContext.vhtSupportedRxNss =
3996 pStaDs->vhtSupportedRxNss;
3997 if (pAssocRsp->VHTCaps.present)
3998 vht_caps = &pAssocRsp->VHTCaps;
3999 else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
4000 vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
4001 lim_log(pMac, LOG1, FL(
4002 "VHT Caps are in vendor Specfic IE"));
4003 }
4004
4005 if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
4006 vht_caps->muBeamformerCap) &&
4007 psessionEntry->txBFIniFeatureEnabled)
4008 sta_context->vhtTxBFCapable = 1;
4009
4010 if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
4011 psessionEntry->txMuBformee)
4012 sta_context->vhtTxMUBformeeCapable = 1;
4013 if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
4014 psessionEntry->enable_su_tx_bformer)
4015 sta_context->enable_su_tx_bformer = 1;
4016 }
4017
4018 if ((pAssocRsp->HTCaps.supportedChannelWidthSet) &&
4019 (chanWidthSupp)) {
4020 pAddBssParams->staContext.ch_width = (uint8_t)
4021 pAssocRsp->HTInfo.recommendedTxWidthSet;
4022 if (pAssocRsp->VHTCaps.present)
4023 vht_oper = &pAssocRsp->VHTOperation;
4024 else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
4025 vht_oper = &pAssocRsp->vendor2_ie.VHTOperation;
4026 lim_log(pMac, LOG1, FL(
4027 "VHT Op IE is in vendor Specfic IE"));
4028 }
Naveen Rawatc0c91cd2015-11-05 14:27:37 -08004029 /*
4030 * in limExtractApCapability function intersection of FW
4031 * advertised channel width and AP advertised channel
4032 * width has been taken into account for calculating
4033 * psessionEntry->ch_width
4034 */
4035 pAddBssParams->staContext.ch_width =
4036 psessionEntry->ch_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004037
4038 lim_log(pMac, LOGE, FL(
4039 "StaCtx: vhtCap %d ChBW %d TxBF %d"),
4040 pAddBssParams->staContext.vhtCapable,
4041 pAddBssParams->staContext.ch_width,
4042 sta_context->vhtTxBFCapable);
4043 lim_log(pMac, LOGE, FL("StaContext su_tx_bfer %d"),
4044 sta_context->enable_su_tx_bformer);
4045 } else {
4046 sta_context->ch_width = CH_WIDTH_20MHZ;
4047 if ((IS_SIR_STATUS_SUCCESS(
4048 wlan_cfg_get_int(pMac,
4049 WNI_CFG_VHT_ENABLE_TXBF_20MHZ,
4050 &enableTxBF20MHz))) &&
4051 (false == enableTxBF20MHz))
4052 sta_context->vhtTxBFCapable = 0;
4053 }
4054 pAddBssParams->staContext.mimoPS =
4055 (tSirMacHTMIMOPowerSaveState)
4056 pAssocRsp->HTCaps.mimoPowerSave;
4057 pAddBssParams->staContext.maxAmsduSize =
4058 (uint8_t) pAssocRsp->HTCaps.maximalAMSDUsize;
4059 pAddBssParams->staContext.maxAmpduDensity =
4060 pAssocRsp->HTCaps.mpduDensity;
4061 pAddBssParams->staContext.fDsssCckMode40Mhz =
4062 (uint8_t) pAssocRsp->HTCaps.dsssCckMode40MHz;
4063 /*
4064 * We will check gShortGI20Mhz and gShortGI40Mhz from
4065 * ini file. if they are set then we will use what ever
4066 * Assoc response coming from AP supports. If these
4067 * values are set as 0 in ini file then we will
4068 * hardcode this values to 0.
4069 */
4070 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
4071 (pMac, WNI_CFG_SHORT_GI_20MHZ,
4072 &shortGi20MhzSupport))) {
4073 if (true == shortGi20MhzSupport) {
4074 pAddBssParams->staContext.
4075 fShortGI20Mhz =
4076 (uint8_t) pAssocRsp->HTCaps.
4077 shortGI20MHz;
4078 } else {
4079 pAddBssParams->staContext.
4080 fShortGI20Mhz = false;
4081 }
4082 } else {
4083 lim_log(pMac, LOGE, FL(
4084 "failed to get shortGI 20Mhz, set default"));
4085 pAddBssParams->staContext.fShortGI20Mhz =
4086 WNI_CFG_SHORT_GI_20MHZ_STADEF;
4087 }
4088
4089 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
4090 (pMac, WNI_CFG_SHORT_GI_40MHZ,
4091 &shortGi40MhzSupport))) {
4092 if (true == shortGi40MhzSupport) {
4093 pAddBssParams->staContext.
4094 fShortGI40Mhz =
4095 (uint8_t) pAssocRsp->HTCaps.
4096 shortGI40MHz;
4097 } else {
4098 pAddBssParams->staContext.
4099 fShortGI40Mhz = false;
4100 }
4101 } else {
4102 lim_log(pMac, LOGE, FL(
4103 "failed to get shortGI 40Mhz, set default"));
4104 pAddBssParams->staContext.fShortGI40Mhz =
4105 WNI_CFG_SHORT_GI_40MHZ_STADEF;
4106 }
4107
4108 if (!pAddBssParams->staContext.vhtCapable)
4109 /* Use max ampd factor advertised in
4110 * HTCAP for non-vht connection */
4111 {
4112 pAddBssParams->staContext.maxAmpduSize =
4113 pAssocRsp->HTCaps.maxRxAMPDUFactor;
4114 } else if (pAddBssParams->staContext.maxAmpduSize <
4115 pAssocRsp->HTCaps.maxRxAMPDUFactor) {
4116 pAddBssParams->staContext.maxAmpduSize =
4117 pAssocRsp->HTCaps.maxRxAMPDUFactor;
4118 }
4119 if (pAddBssParams->staContext.vhtTxBFCapable
4120 && pMac->lim.disableLDPCWithTxbfAP) {
4121 pAddBssParams->staContext.htLdpcCapable = 0;
4122 pAddBssParams->staContext.vhtLdpcCapable = 0;
4123 } else {
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004124 if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
4125 pAddBssParams->staContext.htLdpcCapable =
4126 (uint8_t) pAssocRsp->HTCaps.advCodingCap;
4127 else
4128 pAddBssParams->staContext.htLdpcCapable = 0;
4129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130 if (pAssocRsp->VHTCaps.present)
4131 vht_caps = &pAssocRsp->VHTCaps;
4132 else if (pAssocRsp->vendor2_ie.VHTCaps.present) {
4133 vht_caps = &pAssocRsp->vendor2_ie.VHTCaps;
4134 lim_log(pMac, LOG1, FL(
4135 "VHT Caps is in vendor Specfic IE"));
4136 }
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004137 if (vht_caps != NULL &&
4138 (psessionEntry->txLdpcIniFeatureEnabled & 0x2))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004139 pAddBssParams->staContext.vhtLdpcCapable =
4140 (uint8_t) vht_caps->ldpcCodingCap;
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004141 else
4142 pAddBssParams->staContext.vhtLdpcCapable = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 }
4144
4145 if (pBeaconStruct->HTInfo.present)
4146 pAddBssParams->staContext.rifsMode =
4147 pAssocRsp->HTInfo.rifsMode;
4148
4149 lim_log(pMac, LOGE, FL(
4150 "StaCtx: ChBW %d mimoPS %d maxAmsduSize %d"),
4151 pAddBssParams->staContext.ch_width,
4152 pAddBssParams->staContext.mimoPS,
4153 pAddBssParams->staContext.maxAmsduSize);
4154
4155 lim_log(pMac, LOG2, FL(
4156 "maxAmpduDens %d CckMode40Mhz %d SGI20Mhz %d"),
4157 pAddBssParams->staContext.maxAmpduDensity,
4158 pAddBssParams->staContext.fDsssCckMode40Mhz,
4159 pAddBssParams->staContext.fShortGI20Mhz);
4160
4161 lim_log(pMac, LOG2, FL(
4162 "SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d"),
4163 pAddBssParams->staContext.fShortGI40Mhz,
4164 pAddBssParams->staContext.maxAmpduSize,
4165 pAddBssParams->staContext.htLdpcCapable,
4166 pAddBssParams->staContext.vhtLdpcCapable);
4167 }
4168 pAddBssParams->staContext.smesessionId =
4169 psessionEntry->smeSessionId;
4170 pAddBssParams->staContext.wpa_rsn = pBeaconStruct->rsnPresent;
4171 pAddBssParams->staContext.wpa_rsn |=
4172 (pBeaconStruct->wpaPresent << 1);
4173 /* For OSEN Connection AP does not advertise RSN or WPA IE
4174 * so from the IEs we get from supplicant we get this info
4175 * so for FW to transmit EAPOL message 4 we shall set
4176 * wpa_rsn
4177 */
4178 if ((!pAddBssParams->staContext.wpa_rsn)
4179 && (psessionEntry->isOSENConnection))
4180 pAddBssParams->staContext.wpa_rsn = 1;
4181 cdf_mem_copy(&pAddBssParams->staContext.capab_info,
4182 &pAssocRsp->capabilityInfo,
4183 sizeof(pAddBssParams->staContext.capab_info));
4184 cdf_mem_copy(&pAddBssParams->staContext.ht_caps,
4185 (uint8_t *) &pAssocRsp->HTCaps + sizeof(uint8_t),
4186 sizeof(pAddBssParams->staContext.ht_caps));
4187
4188 /* If WMM IE or 802.11E IE is present then enable WMM */
4189 if ((psessionEntry->limWmeEnabled && pAssocRsp->wmeEdcaPresent) ||
4190 (psessionEntry->limQosEnabled && pAssocRsp->edcaPresent))
4191 pAddBssParams->staContext.wmmEnabled = 1;
4192 else
4193 pAddBssParams->staContext.wmmEnabled = 0;
4194
4195 /* Update the rates */
4196 pStaDs = dph_get_hash_entry(pMac, DPH_STA_HASH_INDEX_PEER,
4197 &psessionEntry->dph.dphHashTable);
4198 if (pStaDs != NULL) {
4199 lim_fill_supported_rates_info(pMac, pStaDs,
4200 &pStaDs->supportedRates,
4201 psessionEntry);
4202 cdf_mem_copy((uint8_t *) &pAddBssParams->staContext.
4203 supportedRates,
4204 (uint8_t *) &pStaDs->supportedRates,
4205 sizeof(tSirSupportedRates));
4206 } else
4207 lim_log(pMac, LOGE, FL(
4208 "could not Update the supported rates"));
4209 pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
4210
4211#if defined WLAN_FEATURE_VOWIFI
4212 pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
4213 lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
4214#endif
4215 /* FIXME_GEN4 - Any other value that can be used for initialization? */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304216 pAddBssParams->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004217 pAddBssParams->respReqd = true;
4218 /* update persona */
4219 pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona;
4220
Anurag Chouhan6d760662016-02-20 16:05:43 +05304221 if (QDF_P2P_CLIENT_MODE == psessionEntry->pePersona)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222 pAddBssParams->staContext.p2pCapableSta = 1;
4223
4224 pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
4225
4226#if defined WLAN_FEATURE_VOWIFI_11R
4227 pAddBssParams->extSetStaKeyParamValid = 0;
4228 lim_log(pMac, LOG2, FL("extSetStaKeyParamValid: %d"),
4229 pAddBssParams->extSetStaKeyParamValid);
4230#endif
4231
4232#ifdef WLAN_FEATURE_11W
4233 if (psessionEntry->limRmfEnabled) {
4234 pAddBssParams->rmfEnabled = 1;
4235 pAddBssParams->staContext.rmfEnabled = 1;
4236 }
4237#endif
4238
4239 /* Set a new state for MLME */
4240 if (eLIM_MLM_WT_ASSOC_RSP_STATE == psessionEntry->limMlmState)
4241 psessionEntry->limMlmState =
4242 eLIM_MLM_WT_ADD_BSS_RSP_ASSOC_STATE;
4243 else
4244 psessionEntry->limMlmState =
4245 eLIM_MLM_WT_ADD_BSS_RSP_REASSOC_STATE;
4246 MTRACE(mac_trace
4247 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
4248 psessionEntry->limMlmState));
4249
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004250 if (!pAddBssParams->staContext.htLdpcCapable)
4251 pAddBssParams->staContext.ht_caps &=
4252 ~(1 << SIR_MAC_HT_CAP_ADVCODING_S);
4253 if (!pAddBssParams->staContext.vhtLdpcCapable)
4254 pAddBssParams->staContext.vht_caps &=
4255 ~(1 << SIR_MAC_VHT_CAP_LDPC_CODING_CAP);
4256
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004257 lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
4258 "p2pCapableSta: %d"),
4259 pAddBssParams->staContext.wmmEnabled,
4260 pAddBssParams->staContext.encryptType,
4261 pAddBssParams->staContext.p2pCapableSta);
4262
4263 lim_log(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
4264 "LimMlm state to %d"),
4265 pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
4266 psessionEntry->limMlmState);
4267 if (psessionEntry->isNonRoamReassoc)
4268 pAddBssParams->nonRoamReassoc = 1;
4269 pAddBssParams->nss = psessionEntry->nss;
4270 lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);
4271
4272 /* we need to defer the message until we get the response back from HAL. */
4273 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
4274
4275 msgQ.type = WMA_ADD_BSS_REQ;
4276 /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
4277 msgQ.reserved = 0;
4278 msgQ.bodyptr = pAddBssParams;
4279 msgQ.bodyval = 0;
4280
4281 lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
4282 psessionEntry->peSessionId);
4283 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
4284
4285 retCode = wma_post_ctrl_msg(pMac, &msgQ);
4286 if (eSIR_SUCCESS != retCode) {
4287 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
4288 cdf_mem_free(pAddBssParams);
4289 lim_log(pMac, LOGE,
4290 FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
4291 retCode);
4292 goto returnFailure;
4293
4294 } else
4295 return retCode;
4296
4297returnFailure:
4298 /* Clean-up will be done by the caller... */
4299 return retCode;
4300}
4301
4302tSirRetStatus lim_sta_send_add_bss_pre_assoc(tpAniSirGlobal pMac, uint8_t updateEntry,
4303 tpPESession psessionEntry)
4304{
4305 tSirMsgQ msgQ;
4306 tpAddBssParams pAddBssParams = NULL;
4307 uint32_t retCode;
4308 tSchBeaconStruct *pBeaconStruct;
4309 uint8_t chanWidthSupp = 0;
4310 uint32_t shortGi20MhzSupport;
4311 uint32_t shortGi40MhzSupport;
4312 tDot11fIEVHTOperation *vht_oper = NULL;
4313 tDot11fIEVHTCaps *vht_caps = NULL;
4314
4315 tpSirBssDescription bssDescription =
4316 &psessionEntry->pLimJoinReq->bssDescription;
4317
4318 pBeaconStruct = cdf_mem_malloc(sizeof(tSchBeaconStruct));
4319 if (NULL == pBeaconStruct) {
4320 lim_log(pMac, LOGE,
4321 FL("Unable to allocate memory during ADD_BSS"));
4322 return eSIR_MEM_ALLOC_FAILED;
4323 }
4324
4325 /* Package SIR_HAL_ADD_BSS_REQ message parameters */
4326 pAddBssParams = cdf_mem_malloc(sizeof(tAddBssParams));
4327 if (NULL == pAddBssParams) {
4328 lim_log(pMac, LOGP,
4329 FL("Unable to allocate memory during ADD_BSS"));
4330 retCode = eSIR_MEM_ALLOC_FAILED;
4331 goto returnFailure;
4332 }
4333
4334 cdf_mem_set((uint8_t *) pAddBssParams, sizeof(tAddBssParams), 0);
4335
4336 lim_extract_ap_capabilities(pMac, (uint8_t *) bssDescription->ieFields,
4337 lim_get_ielen_from_bss_description(bssDescription),
4338 pBeaconStruct);
4339
4340 if (pMac->lim.gLimProtectionControl !=
4341 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
4342 lim_decide_sta_protection_on_assoc(pMac, pBeaconStruct,
4343 psessionEntry);
4344 cdf_mem_copy(pAddBssParams->bssId, bssDescription->bssId,
4345 sizeof(tSirMacAddr));
4346
4347 /* Fill in tAddBssParams selfMacAddr */
4348 cdf_mem_copy(pAddBssParams->selfMacAddr,
4349 psessionEntry->selfMacAddr, sizeof(tSirMacAddr));
4350 lim_log(pMac, LOG1,
4351 FL("sessionid: %d updateEntry = %d limsystemrole = %d "),
4352 psessionEntry->smeSessionId, updateEntry,
4353 GET_LIM_SYSTEM_ROLE(psessionEntry));
4354
4355 lim_log(pMac, LOG1, FL("BSSID: " MAC_ADDRESS_STR),
4356 MAC_ADDR_ARRAY(pAddBssParams->bssId));
4357 /* Incorrect BSS Type which caused UMA Descriptor to be overwritten on
4358 * top of an already established Infra link. This lead to issues in
4359 * concurrent data transfer.
4360 */
4361
4362 pAddBssParams->bssType = psessionEntry->bssType; /* eSIR_INFRASTRUCTURE_MODE; */
4363 pAddBssParams->operMode = BSS_OPERATIONAL_MODE_STA;
4364
4365 pAddBssParams->beaconInterval = bssDescription->beaconInterval;
4366
4367 pAddBssParams->dtimPeriod = pBeaconStruct->tim.dtimPeriod;
4368 pAddBssParams->updateBss = updateEntry;
4369
4370 pAddBssParams->cfParamSet.cfpCount = pBeaconStruct->cfParamSet.cfpCount;
4371 pAddBssParams->cfParamSet.cfpPeriod =
4372 pBeaconStruct->cfParamSet.cfpPeriod;
4373 pAddBssParams->cfParamSet.cfpMaxDuration =
4374 pBeaconStruct->cfParamSet.cfpMaxDuration;
4375 pAddBssParams->cfParamSet.cfpDurRemaining =
4376 pBeaconStruct->cfParamSet.cfpDurRemaining;
4377
4378 pAddBssParams->rateSet.numRates =
4379 pBeaconStruct->supportedRates.numRates;
4380 cdf_mem_copy(pAddBssParams->rateSet.rate,
4381 pBeaconStruct->supportedRates.rate,
4382 pBeaconStruct->supportedRates.numRates);
4383
4384 pAddBssParams->nwType = bssDescription->nwType;
4385
4386 pAddBssParams->shortSlotTimeSupported =
4387 (uint8_t) pBeaconStruct->capabilityInfo.shortSlotTime;
4388 pAddBssParams->llaCoexist =
4389 (uint8_t) psessionEntry->beaconParams.llaCoexist;
4390 pAddBssParams->llbCoexist =
4391 (uint8_t) psessionEntry->beaconParams.llbCoexist;
4392 pAddBssParams->llgCoexist =
4393 (uint8_t) psessionEntry->beaconParams.llgCoexist;
4394 pAddBssParams->ht20Coexist =
4395 (uint8_t) psessionEntry->beaconParams.ht20Coexist;
4396
4397 lim_log(pMac, LOG2, FL(" BSS Type %d Beacon Interval: %d dtimPeriod: %d "
4398 "cfpCount: %d"), pAddBssParams->bssType,
4399 pAddBssParams->beaconInterval, pAddBssParams->dtimPeriod,
4400 pAddBssParams->cfParamSet.cfpCount);
4401
4402 lim_log(pMac, LOG2,
4403 FL(" cfpPeriod: %d cfpMaxDuration: %d cfpDurRemaining:"
4404 " %d numRates: %d "), pAddBssParams->cfParamSet.cfpPeriod,
4405 pAddBssParams->cfParamSet.cfpMaxDuration,
4406 pAddBssParams->cfParamSet.cfpDurRemaining,
4407 pAddBssParams->rateSet.numRates);
4408
4409 lim_log(pMac, LOG2, FL("nwType:%d shortSlotTimeSupported: %d"
4410 "llaCoexist: %d llbCoexist: %d llgCoexist: %d ht20Coexist: %d"),
4411 pAddBssParams->nwType, pAddBssParams->shortSlotTimeSupported,
4412 pAddBssParams->llaCoexist, pAddBssParams->llbCoexist,
4413 pAddBssParams->llgCoexist, pAddBssParams->ht20Coexist);
4414 /* Use the advertised capabilities from the received beacon/PR */
4415 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
4416 && (pBeaconStruct->HTCaps.present)) {
4417 pAddBssParams->htCapable = pBeaconStruct->HTCaps.present;
4418 lim_log(pMac, LOG2, FL("htCapable: %d"),
4419 pAddBssParams->htCapable);
4420 if (pBeaconStruct->HTInfo.present) {
4421 pAddBssParams->htOperMode =
4422 (tSirMacHTOperatingMode) pBeaconStruct->HTInfo.
4423 opMode;
4424 pAddBssParams->dualCTSProtection =
4425 (uint8_t) pBeaconStruct->HTInfo.dualCTSProtection;
4426
4427 chanWidthSupp =
4428 lim_get_ht_capability(pMac,
4429 eHT_SUPPORTED_CHANNEL_WIDTH_SET,
4430 psessionEntry);
4431 if ((pBeaconStruct->HTCaps.supportedChannelWidthSet)
4432 && (chanWidthSupp)) {
4433 pAddBssParams->ch_width =
4434 (uint8_t) pBeaconStruct->HTInfo.
4435 recommendedTxWidthSet;
4436 if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
4437 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
4438 pAddBssParams->ch_center_freq_seg0 =
4439 bssDescription->channelId + 2;
4440
4441 if (pBeaconStruct->HTInfo.secondaryChannelOffset ==
4442 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
4443 pAddBssParams->ch_center_freq_seg0 =
4444 bssDescription->channelId - 2;
4445 } else {
4446 pAddBssParams->ch_width = CH_WIDTH_20MHZ;
4447 pAddBssParams->ch_center_freq_seg0 = 0;
4448 }
4449 pAddBssParams->llnNonGFCoexist =
4450 (uint8_t) pBeaconStruct->HTInfo.nonGFDevicesPresent;
4451 pAddBssParams->fLsigTXOPProtectionFullSupport =
4452 (uint8_t) pBeaconStruct->HTInfo.
4453 lsigTXOPProtectionFullSupport;
4454 pAddBssParams->fRIFSMode =
4455 pBeaconStruct->HTInfo.rifsMode;
4456
4457 lim_log(pMac, LOG2,
4458 FL("htOperMode: %d dualCTSProtection: %d txChannelWidthSet: %d center_freq_seg0: %d "),
4459 pAddBssParams->htOperMode,
4460 pAddBssParams->dualCTSProtection,
4461 pAddBssParams->txChannelWidthSet,
4462 pAddBssParams->ch_center_freq_seg0);
4463
4464 lim_log(pMac, LOG2, FL("llnNonGFCoexist: %d "
4465 "fLsigTXOPProtectionFullSupport: %d fRIFSMode %d"),
4466 pAddBssParams->llnNonGFCoexist,
4467 pAddBssParams->fLsigTXOPProtectionFullSupport,
4468 pAddBssParams->fRIFSMode);
4469 }
4470 }
4471
4472 pAddBssParams->currentOperChannel = bssDescription->channelId;
4473 lim_log(pMac, LOG2, FL("currentOperChannel %d"),
4474 pAddBssParams->currentOperChannel);
4475#ifdef WLAN_FEATURE_11AC
4476 if (psessionEntry->vhtCapability &&
4477 (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
4478 IS_BSS_VHT_CAPABLE(pBeaconStruct->vendor2_ie.VHTCaps))) {
4479
4480 pAddBssParams->vhtCapable = 1;
4481 if (pBeaconStruct->VHTOperation.present)
4482 vht_oper = &pBeaconStruct->VHTOperation;
4483 else if (pBeaconStruct->vendor2_ie.VHTOperation.present) {
4484 vht_oper = &pBeaconStruct->vendor2_ie.VHTOperation;
4485 lim_log(pMac, LOG1,
4486 FL("VHT Operation is present in vendor Specfic IE"));
4487 }
4488
4489
4490 if ((vht_oper != NULL) &&
4491 vht_oper->chanWidth &&
4492 chanWidthSupp) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004493 pAddBssParams->ch_center_freq_seg0 =
4494 vht_oper->chanCenterFreqSeg1;
4495 pAddBssParams->ch_center_freq_seg1 =
4496 vht_oper->chanCenterFreqSeg2;
4497 }
Naveen Rawatc0c91cd2015-11-05 14:27:37 -08004498 /*
4499 * in limExtractApCapability function intersection of FW
4500 * advertised channel width and AP advertised channel width has
4501 * been taken into account for calculating
4502 * psessionEntry->ch_width
4503 */
4504 pAddBssParams->ch_width =
4505 psessionEntry->ch_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004506 pAddBssParams->staContext.maxAmpduSize =
4507 SIR_MAC_GET_VHT_MAX_AMPDU_EXPO(
4508 pAddBssParams->staContext.vht_caps);
4509 } else {
4510 pAddBssParams->vhtCapable = 0;
4511 }
4512 lim_log(pMac, LOGE, FL("vhtCapable %d vhtTxChannelWidthSet %d center_freq_seg0 - %d, center_freq_seg1 - %d"),
4513 pAddBssParams->vhtCapable, pAddBssParams->ch_width,
4514 pAddBssParams->ch_center_freq_seg0,
4515 pAddBssParams->ch_center_freq_seg1);
4516#endif
4517
4518 /*
4519 * Populate the STA-related parameters here
4520 * Note that the STA here refers to the AP
4521 */
4522 /* Identifying AP as an STA */
4523 pAddBssParams->staContext.staType = STA_ENTRY_OTHER;
4524
4525 cdf_mem_copy(pAddBssParams->staContext.bssId,
4526 bssDescription->bssId, sizeof(tSirMacAddr));
4527 pAddBssParams->staContext.listenInterval =
4528 bssDescription->beaconInterval;
4529
4530 pAddBssParams->staContext.assocId = 0;
4531 pAddBssParams->staContext.uAPSD = 0;
4532 pAddBssParams->staContext.maxSPLen = 0;
4533 pAddBssParams->staContext.shortPreambleSupported =
4534 (uint8_t) pBeaconStruct->capabilityInfo.shortPreamble;
4535 pAddBssParams->staContext.updateSta = updateEntry;
4536
4537 lim_log(pMac, LOG2, FL(
4538 "StaCtx: " MAC_ADDRESS_STR " shortPreamble: %d"),
4539 MAC_ADDR_ARRAY(pAddBssParams->staContext.staMac),
4540 pAddBssParams->staContext.shortPreambleSupported);
4541
4542 pAddBssParams->dot11_mode = psessionEntry->dot11mode;
4543 lim_log(pMac, LOG2, FL("dot11_mode:%d"),
4544 pAddBssParams->dot11_mode);
4545
4546 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)
4547 && (pBeaconStruct->HTCaps.present)) {
4548 pAddBssParams->staContext.us32MaxAmpduDuration = 0;
4549 pAddBssParams->staContext.htCapable = 1;
4550 pAddBssParams->staContext.greenFieldCapable =
4551 (uint8_t) pBeaconStruct->HTCaps.greenField;
4552 pAddBssParams->staContext.lsigTxopProtection =
4553 (uint8_t) pBeaconStruct->HTCaps.lsigTXOPProtection;
4554 lim_log(pMac, LOG2, FL(
4555 "StaCtx: htCap %d GFCap %d lsigTxopProtn %d"),
4556 pAddBssParams->staContext.htCapable,
4557 pAddBssParams->staContext.greenFieldCapable,
4558 pAddBssParams->staContext.lsigTxopProtection);
4559 if (psessionEntry->vhtCapability &&
4560 (IS_BSS_VHT_CAPABLE(pBeaconStruct->VHTCaps) ||
4561 IS_BSS_VHT_CAPABLE(
4562 pBeaconStruct->vendor2_ie.VHTCaps))) {
4563 pAddBssParams->staContext.vhtCapable = 1;
4564 if (pBeaconStruct->VHTCaps.present)
4565 vht_caps = &pBeaconStruct->VHTCaps;
4566 else if (pBeaconStruct->vendor2_ie.VHTCaps.present)
4567 vht_caps = &pBeaconStruct->vendor2_ie.VHTCaps;
4568
4569 if ((vht_caps != NULL) && (vht_caps->suBeamFormerCap ||
4570 vht_caps->muBeamformerCap) &&
4571 psessionEntry->txBFIniFeatureEnabled)
4572 pAddBssParams->staContext.vhtTxBFCapable = 1;
4573
4574 if ((vht_caps != NULL) && vht_caps->muBeamformerCap &&
4575 psessionEntry->txMuBformee)
4576 pAddBssParams->staContext.vhtTxMUBformeeCapable
4577 = 1;
4578 if ((vht_caps != NULL) && vht_caps->suBeamformeeCap &&
4579 psessionEntry->enable_su_tx_bformer)
4580 pAddBssParams->staContext.enable_su_tx_bformer
4581 = 1;
4582 lim_log(pMac, LOG2, FL("StaContext: su_tx_bfer %d"),
4583 pAddBssParams->staContext.enable_su_tx_bformer);
4584 }
4585 if ((pBeaconStruct->HTCaps.supportedChannelWidthSet) &&
4586 (chanWidthSupp)) {
4587 pAddBssParams->staContext.ch_width =
4588 (uint8_t) pBeaconStruct->HTInfo.
4589 recommendedTxWidthSet;
4590 if ((vht_oper != NULL) &&
4591 pAddBssParams->staContext.vhtCapable &&
4592 vht_oper->chanWidth)
4593 pAddBssParams->staContext.ch_width =
4594 vht_oper->chanWidth + 1;
4595 lim_log(pMac, LOG2, FL(
4596 "StaCtx: vhtCap %d ch_bw %d TxBF %d"),
4597 pAddBssParams->staContext.vhtCapable,
4598 pAddBssParams->staContext.ch_width,
4599 pAddBssParams->staContext.
4600 vhtTxBFCapable);
4601 } else {
4602 pAddBssParams->staContext.ch_width =
4603 CH_WIDTH_20MHZ;
4604 }
4605 pAddBssParams->staContext.mimoPS =
4606 (tSirMacHTMIMOPowerSaveState) pBeaconStruct->HTCaps.
4607 mimoPowerSave;
4608 pAddBssParams->staContext.maxAmsduSize =
4609 (uint8_t) pBeaconStruct->HTCaps.maximalAMSDUsize;
4610 pAddBssParams->staContext.maxAmpduDensity =
4611 pBeaconStruct->HTCaps.mpduDensity;
4612 pAddBssParams->staContext.fDsssCckMode40Mhz =
4613 (uint8_t) pBeaconStruct->HTCaps.dsssCckMode40MHz;
4614 /*
4615 * We will check gShortGI20Mhz and gShortGI40Mhz from ini file.
4616 * if they are set then we will use what ever Beacon coming
4617 * from AP supports. If these values are set as 0 in ini file
4618 * then we will hardcode this values to 0.
4619 */
4620 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
4621 (pMac, WNI_CFG_SHORT_GI_20MHZ,
4622 &shortGi20MhzSupport))) {
4623 if (true == shortGi20MhzSupport)
4624 pAddBssParams->staContext.fShortGI20Mhz =
4625 (uint8_t)pBeaconStruct->HTCaps.shortGI20MHz;
4626 else
4627 pAddBssParams->staContext.fShortGI20Mhz =
4628 false;
4629 } else {
4630 lim_log(pMac, LOGE, FL(
4631 "get shortGI 20Mhz failed, set default"));
4632 pAddBssParams->staContext.fShortGI20Mhz =
4633 WNI_CFG_SHORT_GI_20MHZ_STADEF;
4634 }
4635
4636 if (IS_SIR_STATUS_SUCCESS(wlan_cfg_get_int
4637 (pMac, WNI_CFG_SHORT_GI_40MHZ,
4638 &shortGi40MhzSupport))) {
4639 if (true == shortGi40MhzSupport) {
4640 pAddBssParams->staContext.
4641 fShortGI40Mhz =
4642 (uint8_t) pBeaconStruct->HTCaps.
4643 shortGI40MHz;
4644 } else {
4645 pAddBssParams->staContext.
4646 fShortGI40Mhz = false;
4647 }
4648 } else {
4649 lim_log(pMac, LOGE, FL(
4650 "get shortGI 40Mhz failed, set default"));
4651 pAddBssParams->staContext.fShortGI40Mhz =
4652 WNI_CFG_SHORT_GI_40MHZ_STADEF;
4653 }
4654
4655 pAddBssParams->staContext.maxAmpduSize =
4656 pBeaconStruct->HTCaps.maxRxAMPDUFactor;
4657 if (pAddBssParams->staContext.vhtTxBFCapable
4658 && pMac->lim.disableLDPCWithTxbfAP) {
4659 pAddBssParams->staContext.htLdpcCapable = 0;
4660 pAddBssParams->staContext.vhtLdpcCapable = 0;
4661 } else {
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004662 if (psessionEntry->txLdpcIniFeatureEnabled & 0x1)
4663 pAddBssParams->staContext.htLdpcCapable =
4664 (uint8_t) pBeaconStruct->HTCaps.
4665 advCodingCap;
4666 else
4667 pAddBssParams->staContext.htLdpcCapable = 0;
4668
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004669 if (pBeaconStruct->VHTCaps.present)
4670 vht_caps = &pBeaconStruct->VHTCaps;
4671 else if (pBeaconStruct->vendor2_ie.VHTCaps.present) {
4672 vht_caps =
4673 &pBeaconStruct->vendor2_ie.VHTCaps;
4674 lim_log(pMac, LOG1, FL(
4675 "VHT Caps are in vendor Specfic IE"));
4676 }
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004677 if (vht_caps != NULL &&
4678 (psessionEntry->txLdpcIniFeatureEnabled & 0x2))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004679 pAddBssParams->staContext.vhtLdpcCapable =
4680 (uint8_t) vht_caps->ldpcCodingCap;
Kiran Kumar Lokere0413ba42015-11-03 14:08:09 -08004681 else
4682 pAddBssParams->staContext.vhtLdpcCapable = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004683 }
4684
4685 if (pBeaconStruct->HTInfo.present)
4686 pAddBssParams->staContext.rifsMode =
4687 pBeaconStruct->HTInfo.rifsMode;
4688 lim_log(pMac, LOG2,
4689 FL("StaContext ChannelWidth: %d mimoPS: %d maxAmsduSize: %d"),
4690 pAddBssParams->staContext.ch_width,
4691 pAddBssParams->staContext.mimoPS,
4692 pAddBssParams->staContext.maxAmsduSize);
4693
4694 lim_log(pMac, LOG2, FL(
4695 "maxAmpduDensity %d Cck40Mhz %d SGI20Mhz %d"),
4696 pAddBssParams->staContext.maxAmpduDensity,
4697 pAddBssParams->staContext.fDsssCckMode40Mhz,
4698 pAddBssParams->staContext.fShortGI20Mhz);
4699
4700 lim_log(pMac, LOG2, FL(
4701 "SGI40M %d maxAmpdu %d htLdpc %d vhtLdpc %d"),
4702 pAddBssParams->staContext.fShortGI40Mhz,
4703 pAddBssParams->staContext.maxAmpduSize,
4704 pAddBssParams->staContext.htLdpcCapable,
4705 pAddBssParams->staContext.vhtLdpcCapable);
4706 }
4707 /*
4708 * If WMM IE or 802.11E IE is not present
4709 * and AP is HT AP then enable WMM
4710 */
4711 if ((psessionEntry->limWmeEnabled && (pBeaconStruct->wmeEdcaPresent ||
4712 pAddBssParams->staContext.htCapable)) ||
4713 (psessionEntry->limQosEnabled &&
4714 (pBeaconStruct->edcaPresent ||
4715 pAddBssParams->staContext.htCapable)))
4716 pAddBssParams->staContext.wmmEnabled = 1;
4717 else
4718 pAddBssParams->staContext.wmmEnabled = 0;
4719
4720 /* Update the rates */
4721#ifdef WLAN_FEATURE_11AC
4722 lim_populate_peer_rate_set(pMac,
4723 &pAddBssParams->staContext.
4724 supportedRates,
4725 pBeaconStruct->HTCaps.supportedMCSSet,
4726 false, psessionEntry,
4727 &pBeaconStruct->VHTCaps);
4728#else
4729 lim_populate_peer_rate_set(pMac,
4730 &pAddBssParams->staContext.
4731 supportedRates,
4732 pBeaconStruct->HTCaps.supportedMCSSet,
4733 false, psessionEntry);
4734#endif
4735 lim_fill_supported_rates_info(pMac, NULL,
4736 &pAddBssParams->staContext.
4737 supportedRates, psessionEntry);
4738
4739
4740 pAddBssParams->staContext.encryptType = psessionEntry->encryptType;
4741
4742#if defined WLAN_FEATURE_VOWIFI
4743 pAddBssParams->maxTxPower = psessionEntry->maxTxPower;
4744 lim_log(pMac, LOG2, FL("maxTxPower: %d"), pAddBssParams->maxTxPower);
4745#endif
4746
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304747 pAddBssParams->status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004748 pAddBssParams->respReqd = true;
4749
4750 pAddBssParams->staContext.smesessionId = psessionEntry->smeSessionId;
4751 pAddBssParams->staContext.sessionId = psessionEntry->peSessionId;
4752 pAddBssParams->sessionId = psessionEntry->peSessionId;
4753
4754 pAddBssParams->halPersona = (uint8_t) psessionEntry->pePersona; /* update persona */
4755
4756 pAddBssParams->bSpectrumMgtEnabled = psessionEntry->spectrumMgtEnabled;
4757
4758#if defined WLAN_FEATURE_VOWIFI_11R
4759 pAddBssParams->extSetStaKeyParamValid = 0;
4760 lim_log(pMac, LOG2, FL("extSetStaKeyParamValid: %d"),
4761 pAddBssParams->extSetStaKeyParamValid);
4762#endif
4763
4764#ifdef WLAN_FEATURE_11W
4765 if (psessionEntry->limRmfEnabled) {
4766 pAddBssParams->rmfEnabled = 1;
4767 pAddBssParams->staContext.rmfEnabled = 1;
4768 }
4769#endif
4770
4771 pAddBssParams->nss = psessionEntry->nss;
4772 lim_log(pMac, LOG2, FL("nss value: %d"), pAddBssParams->nss);
4773
4774 /* Set a new state for MLME */
4775 psessionEntry->limMlmState = eLIM_MLM_WT_ADD_BSS_RSP_PREASSOC_STATE;
4776
4777 MTRACE(mac_trace
4778 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
4779 psessionEntry->limMlmState));
4780
4781 lim_log(pMac, LOG2, FL("staContext wmmEnabled: %d encryptType: %d "
4782 "p2pCapableSta: %d"),
4783 pAddBssParams->staContext.wmmEnabled,
4784 pAddBssParams->staContext.encryptType,
4785 pAddBssParams->staContext.p2pCapableSta);
4786
4787 lim_log(pMac, LOG2, FL("bSpectrumMgtEnabled: %d halPersona: %d setting "
4788 "LimMlm state to %d"),
4789 pAddBssParams->bSpectrumMgtEnabled, pAddBssParams->halPersona,
4790 psessionEntry->limMlmState);
4791
4792 /* we need to defer the message until we get the response back from HAL. */
4793 SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
4794
4795 msgQ.type = WMA_ADD_BSS_REQ;
4796 /** @ToDo : Update the Global counter to keeptrack of the PE <--> HAL messages*/
4797 msgQ.reserved = 0;
4798 msgQ.bodyptr = pAddBssParams;
4799 msgQ.bodyval = 0;
4800
4801 lim_log(pMac, LOG1, FL("SessionId:%d Sending WMA_ADD_BSS_REQ"),
4802 psessionEntry->peSessionId);
4803 MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
4804
4805 retCode = wma_post_ctrl_msg(pMac, &msgQ);
4806 if (eSIR_SUCCESS != retCode) {
4807 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
4808 cdf_mem_free(pAddBssParams);
4809 lim_log(pMac, LOGE,
4810 FL("Posting ADD_BSS_REQ to HAL failed, reason=%X"),
4811 retCode);
4812 goto returnFailure;
4813
4814 } else {
4815 cdf_mem_free(pBeaconStruct);
4816 return retCode;
4817 }
4818
4819returnFailure:
4820 /* Clean-up will be done by the caller... */
4821 cdf_mem_free(pBeaconStruct);
4822 return retCode;
4823}
4824
4825/**
4826 * lim_prepare_and_send_del_sta_cnf() - prepares and send del sta cnf
4827 *
4828 * @pMac: mac global context
4829 * @pStaDs: sta dph node
4830 * @statusCode: status code
4831 * @psessionEntry: session context
4832 *
4833 * deletes DPH entry, changes the MLM mode for station, calls
4834 * lim_send_del_sta_cnf
4835 *
4836 * Return: void
4837 */
4838void
4839lim_prepare_and_send_del_sta_cnf(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
4840 tSirResultCodes statusCode,
4841 tpPESession psessionEntry)
4842{
4843 uint16_t staDsAssocId = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05304844 struct qdf_mac_addr sta_dsaddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845 tLimMlmStaContext mlmStaContext;
4846
4847 if (pStaDs == NULL) {
4848 PELOGW(lim_log(pMac, LOGW, FL("pStaDs is NULL"));)
4849 return;
4850 }
4851 staDsAssocId = pStaDs->assocId;
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08004852 cdf_mem_copy((uint8_t *) sta_dsaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304853 pStaDs->staAddr, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004854
4855 mlmStaContext = pStaDs->mlmStaContext;
4856 if (LIM_IS_AP_ROLE(psessionEntry) ||
4857 LIM_IS_BT_AMP_AP_ROLE(psessionEntry)) {
4858 lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
4859 }
4860 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, pStaDs->assocId,
4861 psessionEntry);
4862
4863 if (LIM_IS_STA_ROLE(psessionEntry) ||
4864 LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) {
4865 psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
4866 MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE,
4867 psessionEntry->peSessionId,
4868 psessionEntry->limMlmState));
4869 }
Srinivas Girigowda9efa10e2016-01-04 18:49:40 -08004870 lim_send_del_sta_cnf(pMac, sta_dsaddr, staDsAssocId, mlmStaContext,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004871 statusCode, psessionEntry);
4872}
4873
4874/** -------------------------------------------------------------
4875 \fn lim_get_sta_rate_mode
4876 \brief Gets the Station Rate Mode.
4877 \param uint8_t dot11Mode
4878 \return none
4879 -------------------------------------------------------------*/
4880tStaRateMode lim_get_sta_rate_mode(uint8_t dot11Mode)
4881{
4882 switch (dot11Mode) {
4883 case WNI_CFG_DOT11_MODE_11A:
4884 return eSTA_11a;
4885 case WNI_CFG_DOT11_MODE_11B:
4886 return eSTA_11b;
4887 case WNI_CFG_DOT11_MODE_11G:
4888 return eSTA_11bg;
4889 case WNI_CFG_DOT11_MODE_11N:
4890 return eSTA_11n;
4891#ifdef WLAN_FEATURE_11AC
4892 case WNI_CFG_DOT11_MODE_11AC:
4893 return eSTA_11ac;
4894#endif
4895 case WNI_CFG_DOT11_MODE_ALL:
4896 default:
4897 return eSTA_11n;
4898
4899 }
4900}
4901
4902/** -------------------------------------------------------------
4903 \fn lim_init_pre_auth_timer_table
4904 \brief Initialize the Pre Auth Tanle and creates the timer for
4905 each node for the timeout value got from cfg.
4906 \param tpAniSirGlobal pMac
4907 \param tpLimPreAuthTable pPreAuthTimerTable
4908 \return none
4909 -------------------------------------------------------------*/
4910void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
4911 tpLimPreAuthTable pPreAuthTimerTable)
4912{
4913 uint32_t cfgValue;
4914 uint32_t authNodeIdx;
4915 tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable;
4916
4917 /* Get AUTH_RSP Timers value */
4918
4919 if (wlan_cfg_get_int(pMac, WNI_CFG_AUTHENTICATE_RSP_TIMEOUT,
4920 &cfgValue) != eSIR_SUCCESS) {
4921 /*
4922 ** Could not get AUTH_RSP timeout value
4923 ** from CFG. Log error.
4924 **/
4925 lim_log(pMac, LOGP,
4926 FL("could not retrieve AUTH_RSP timeout value"));
4927 return;
4928 }
4929
4930 cfgValue = SYS_MS_TO_TICKS(cfgValue);
4931 for (authNodeIdx = 0; authNodeIdx < pPreAuthTimerTable->numEntry;
4932 authNodeIdx++, pAuthNode++) {
Naveen Rawat22b1a932015-08-26 12:13:18 -07004933 if (tx_timer_create(pMac, &pAuthNode->timer,
4934 "AUTH RESPONSE TIMEOUT",
4935 lim_auth_response_timer_handler, authNodeIdx,
4936 cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004937 /* Cannot create timer. Log error. */
4938 lim_log(pMac, LOGP,
4939 FL("Cannot create Auth Rsp timer of Index :%d."),
4940 authNodeIdx);
4941 return;
4942 }
4943 pAuthNode->authNodeIdx = (uint8_t) authNodeIdx;
4944 pAuthNode->fFree = 1;
4945 }
4946
4947}
4948
4949/** -------------------------------------------------------------
4950 \fn lim_acquire_free_pre_auth_node
4951 \brief Retrives a free Pre Auth node from Pre Auth Table.
4952 \param tpAniSirGlobal pMac
4953 \param tpLimPreAuthTable pPreAuthTimerTable
4954 \return none
4955 -------------------------------------------------------------*/
4956tLimPreAuthNode *lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
4957 tpLimPreAuthTable pPreAuthTimerTable)
4958{
4959 uint32_t i;
4960 tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable;
4961 for (i = 0; i < pPreAuthTimerTable->numEntry; i++, pTempNode++) {
4962 if (pTempNode->fFree == 1) {
4963 pTempNode->fFree = 0;
4964 return pTempNode;
4965 }
4966 }
4967
4968 return NULL;
4969}
4970
4971/** -------------------------------------------------------------
4972 \fn lim_get_pre_auth_node_from_index
4973 \brief Depending on the Index this retrives the pre auth node.
4974 \param tpAniSirGlobal pMac
4975 \param tpLimPreAuthTable pAuthTable
4976 \param uint32_t authNodeIdx
4977 \return none
4978 -------------------------------------------------------------*/
4979tLimPreAuthNode *lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
4980 tpLimPreAuthTable pAuthTable,
4981 uint32_t authNodeIdx)
4982{
4983 if ((authNodeIdx >= pAuthTable->numEntry)
4984 || (pAuthTable->pTable == NULL)) {
4985 lim_log(pMac, LOGE,
4986 FL("Invalid Auth Timer Index : %d NumEntry : %d"),
4987 authNodeIdx, pAuthTable->numEntry);
4988 return NULL;
4989 }
4990
4991 return pAuthTable->pTable + authNodeIdx;
4992}
4993
4994/* Util API to check if the channels supported by STA is within range */
4995tSirRetStatus lim_is_dot11h_supported_channels_valid(tpAniSirGlobal pMac,
4996 tSirAssocReq *assoc)
4997{
4998 /*
4999 * Allow all the stations to join with us.
5000 * 802.11h-2003 11.6.1 => An AP may use the supported channels list for associated STAs
5001 * as an input into an algorithm used to select a new channel for the BSS.
5002 * The specification of the algorithm is beyond the scope of this amendment.
5003 */
5004
5005 return eSIR_SUCCESS;
5006}
5007
5008/* Util API to check if the txpower supported by STA is within range */
5009tSirRetStatus lim_is_dot11h_power_capabilities_in_range(tpAniSirGlobal pMac,
5010 tSirAssocReq *assoc,
5011 tpPESession psessionEntry)
5012{
Amar Singhala297bfa2015-10-15 15:07:29 -07005013 int8_t localMaxTxPower;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005014 uint32_t localPwrConstraint;
5015
5016 localMaxTxPower =
5017 cfg_get_regulatory_max_transmit_power(pMac,
5018 psessionEntry->currentOperChannel);
5019
5020 if (wlan_cfg_get_int
5021 (pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT,
5022 &localPwrConstraint) != eSIR_SUCCESS) {
5023 lim_log(pMac, LOGP,
5024 FL("Unable to get Local Power Constraint from cfg"));
5025 return eSIR_FAILURE;
5026 }
Amar Singhala297bfa2015-10-15 15:07:29 -07005027 localMaxTxPower -= (int8_t) localPwrConstraint;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005028
5029 /**
5030 * The min Tx Power of the associating station should not be greater than (regulatory
5031 * max tx power - local power constraint configured on AP).
5032 */
5033 if (assoc->powerCapability.minTxPower > localMaxTxPower) {
5034 lim_log(pMac, LOGW,
5035 FL("minTxPower (STA) = %d, localMaxTxPower (AP) = %d"),
5036 assoc->powerCapability.minTxPower, localMaxTxPower);
5037 return eSIR_FAILURE;
5038 }
5039
5040 return eSIR_SUCCESS;
5041}
5042
5043/** -------------------------------------------------------------
5044 \fn lim_fill_rx_highest_supported_rate
5045 \brief Fills in the Rx Highest Supported Data Rate field from
5046 \ the 'supported MCS set' field in HT capability element.
5047 \param tpAniSirGlobal pMac
5048 \param tpSirSupportedRates pRates
5049 \param uint8_t* pSupportedMCSSet
5050 \return none
5051 -------------------------------------------------------------*/
5052void lim_fill_rx_highest_supported_rate(tpAniSirGlobal pMac,
5053 uint16_t *rxHighestRate,
5054 uint8_t *pSupportedMCSSet)
5055{
5056 tSirMacRxHighestSupportRate *pRxHighestRate;
5057 uint8_t *pBuf;
5058 uint16_t rate = 0;
5059
5060 pBuf = pSupportedMCSSet + MCS_RX_HIGHEST_SUPPORTED_RATE_BYTE_OFFSET;
5061 rate = lim_get_u16(pBuf);
5062
5063 pRxHighestRate = (tSirMacRxHighestSupportRate *) &rate;
5064 *rxHighestRate = pRxHighestRate->rate;
5065
5066 return;
5067}
5068
5069#ifdef WLAN_FEATURE_11W
5070/** -------------------------------------------------------------
5071 \fn lim_send_sme_unprotected_mgmt_frame_ind
5072 \brief Forwards the unprotected management frame to SME.
5073 \param tpAniSirGlobal pMac
5074 \param frameType - 802.11 frame type
5075 \param frame - frame buffer
5076 \param sessionId - id for the current session
5077 \param psessionEntry - PE session context
5078 \return none
5079 -------------------------------------------------------------*/
5080void lim_send_sme_unprotected_mgmt_frame_ind(tpAniSirGlobal pMac, uint8_t frameType,
5081 uint8_t *frame, uint32_t frameLen,
5082 uint16_t sessionId,
5083 tpPESession psessionEntry)
5084{
5085 tSirMsgQ mmhMsg;
5086 tSirSmeUnprotMgmtFrameInd *pSirSmeMgmtFrame = NULL;
5087 uint16_t length;
5088
5089 length = sizeof(tSirSmeUnprotMgmtFrameInd) + frameLen;
5090
5091 pSirSmeMgmtFrame = cdf_mem_malloc(length);
5092 if (NULL == pSirSmeMgmtFrame) {
5093 lim_log(pMac, LOGP,
5094 FL
5095 ("AllocateMemory failed for tSirSmeUnprotectedMgmtFrameInd"));
5096 return;
5097 }
5098 cdf_mem_set((void *)pSirSmeMgmtFrame, length, 0);
5099
5100 pSirSmeMgmtFrame->sessionId = sessionId;
5101 pSirSmeMgmtFrame->frameType = frameType;
5102
5103 cdf_mem_copy(pSirSmeMgmtFrame->frameBuf, frame, frameLen);
5104 pSirSmeMgmtFrame->frameLen = frameLen;
5105
5106 mmhMsg.type = eWNI_SME_UNPROT_MGMT_FRM_IND;
5107 mmhMsg.bodyptr = pSirSmeMgmtFrame;
5108 mmhMsg.bodyval = 0;
5109
5110 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
5111 return;
5112}
5113#endif
5114
5115#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
5116/** -------------------------------------------------------------
5117 \fn lim_send_sme_tsm_ie_ind
5118 \brief Forwards the TSM IE information to SME.
5119 \param tpAniSirGlobal pMac
5120 \param psessionEntry - PE session context
5121 \param tid - traffic id
5122 \param state - tsm state (enabled/disabled)
5123 \param measurementInterval - measurement interval
5124 \return none
5125 -------------------------------------------------------------*/
5126void lim_send_sme_tsm_ie_ind(tpAniSirGlobal pMac, tpPESession psessionEntry,
5127 uint8_t tid, uint8_t state, uint16_t measInterval)
5128{
5129 tSirMsgQ mmhMsg;
5130 tpSirSmeTsmIEInd pSirSmeTsmIeInd = NULL;
5131
5132 if (!pMac || !psessionEntry)
5133 return;
5134
5135 pSirSmeTsmIeInd = cdf_mem_malloc(sizeof(tSirSmeTsmIEInd));
5136 if (NULL == pSirSmeTsmIeInd) {
5137 lim_log(pMac, LOGP,
5138 FL("AllocateMemory failed for tSirSmeTsmIEInd"));
5139 return;
5140 }
5141 cdf_mem_set((void *)pSirSmeTsmIeInd, sizeof(tSirSmeTsmIEInd), 0);
5142
5143 pSirSmeTsmIeInd->sessionId = psessionEntry->smeSessionId;
5144 pSirSmeTsmIeInd->tsmIe.tsid = tid;
5145 pSirSmeTsmIeInd->tsmIe.state = state;
5146 pSirSmeTsmIeInd->tsmIe.msmt_interval = measInterval;
5147
5148 mmhMsg.type = eWNI_SME_TSM_IE_IND;
5149 mmhMsg.bodyptr = pSirSmeTsmIeInd;
5150 mmhMsg.bodyval = 0;
5151
5152 lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
5153 return;
5154}
5155#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */