blob: 21c55503a98e81f6472ed46b4f1183af49c9c62d [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Krishna Kumaar Natarajand1cd56e2016-09-30 08:43:03 -07002 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28#include "cds_api.h"
29#include "ani_global.h"
30#include "sir_common.h"
31#include "wni_cfg.h"
32#include "lim_utils.h"
33#include "lim_assoc_utils.h"
34#include "lim_sta_hash_api.h"
35#include "sch_api.h" /* sch_set_fixed_beacon_fields for IBSS coalesce */
36#include "lim_security_utils.h"
37#include "lim_send_messages.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080038#include "lim_ft_defs.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080039#include "lim_session.h"
40#include "lim_ibss_peer_mgmt.h"
41#include "lim_types.h"
42
43/**
44 * ibss_peer_find
45 *
46 ***FUNCTION:
47 * This function is called while adding a context at
48 * DPH & Polaris for a peer in IBSS.
49 * If peer is found in the list, capabilities from the
50 * returned BSS description are used at DPH node & Polaris.
51 *
52 ***LOGIC:
53 *
54 ***ASSUMPTIONS:
55 *
56 ***NOTE:
57 *
58 * @param macAddr - MAC address of the peer
59 *
60 * @return Pointer to peer node if found, else NULL
61 */
62
63static tLimIbssPeerNode *ibss_peer_find(tpAniSirGlobal pMac,
64 tSirMacAddr macAddr)
65{
66 tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList;
67
68 while (pTempNode != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +053069 if (!qdf_mem_cmp((uint8_t *) macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080070 (uint8_t *) &pTempNode->peerMacAddr,
71 sizeof(tSirMacAddr)))
72 break;
73 pTempNode = pTempNode->next;
74 }
75 return pTempNode;
76} /*** end ibss_peer_find() ***/
77
78/**
79 * ibss_peer_add
80 *
81 ***FUNCTION:
82 * This is called on a STA in IBSS upon receiving Beacon/
83 * Probe Response from a peer.
84 *
85 ***LOGIC:
86 * Node is always added to the front of the list
87 *
88 ***ASSUMPTIONS:
89 *
90 ***NOTE:
91 *
92 * @param pMac - Pointer to Global MAC structure
93 * @param pPeerNode - Pointer to peer node to be added to the list.
94 *
95 * @return None
96 */
97
98static tSirRetStatus
99ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode)
100{
101#ifdef ANI_SIR_IBSS_PEER_CACHING
102 uint32_t numIbssPeers = (2 * pMac->lim.maxStation);
103
104 if (pMac->lim.gLimNumIbssPeers >= numIbssPeers) {
105 /**
106 * Reached max number of peers to be maintained.
107 * Delete last entry & add new entry at the beginning.
108 */
109 tLimIbssPeerNode *pTemp, *pPrev;
110 pTemp = pPrev = pMac->lim.gLimIbssPeerList;
111 while (pTemp->next != NULL) {
112 pPrev = pTemp;
113 pTemp = pTemp->next;
114 }
115 if (pTemp->beacon) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530116 qdf_mem_free(pTemp->beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800117 }
118
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530119 qdf_mem_free(pTemp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800120 pPrev->next = NULL;
121 } else
122#endif
123 pMac->lim.gLimNumIbssPeers++;
124
125 pPeerNode->next = pMac->lim.gLimIbssPeerList;
126 pMac->lim.gLimIbssPeerList = pPeerNode;
127
128 return eSIR_SUCCESS;
129
130} /*** end limAddIbssPeerToList() ***/
131
132/**
133 * ibss_peer_collect
134 *
135 ***FUNCTION:
136 * This is called to collect IBSS peer information
137 * from received Beacon/Probe Response frame from it.
138 *
139 ***LOGIC:
140 *
141 ***ASSUMPTIONS:
142 *
143 ***NOTE:
144 *
145 * @param pMac - Pointer to Global MAC structure
146 * @param pBeacon - Parsed Beacon Frame structure
147 * @param pBD - Pointer to received BD
148 * @param pPeer - Pointer to IBSS peer node
149 *
150 * @return None
151 */
152
153static void
154ibss_peer_collect(tpAniSirGlobal pMac,
155 tpSchBeaconStruct pBeacon,
156 tpSirMacMgmtHdr pHdr,
157 tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
158{
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530159 qdf_mem_copy(pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160
161 pPeer->capabilityInfo = pBeacon->capabilityInfo;
162 pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent;
163 pPeer->edcaPresent = pBeacon->edcaPresent;
164 pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent;
165 pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent;
166
167 if (pBeacon->IBSSParams.present) {
168 pPeer->atimIePresent = pBeacon->IBSSParams.present;
169 pPeer->peerAtimWindowLength = pBeacon->IBSSParams.atim;
170 }
171
172 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
173 (pBeacon->HTCaps.present)) {
174 pPeer->htCapable = pBeacon->HTCaps.present;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530175 qdf_mem_copy((uint8_t *) pPeer->supportedMCSSet,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800176 (uint8_t *) pBeacon->HTCaps.supportedMCSSet,
177 sizeof(pPeer->supportedMCSSet));
178 pPeer->htGreenfield = (uint8_t) pBeacon->HTCaps.greenField;
179 pPeer->htSupportedChannelWidthSet =
180 (uint8_t) pBeacon->HTCaps.supportedChannelWidthSet;
181 pPeer->htMIMOPSState =
182 (tSirMacHTMIMOPowerSaveState) pBeacon->HTCaps.mimoPowerSave;
183 pPeer->htMaxAmsduLength =
184 (uint8_t) pBeacon->HTCaps.maximalAMSDUsize;
185 pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity;
186 pPeer->htDsssCckRate40MHzSupport =
187 (uint8_t) pBeacon->HTCaps.dsssCckMode40MHz;
188 pPeer->htShortGI20Mhz = (uint8_t) pBeacon->HTCaps.shortGI20MHz;
189 pPeer->htShortGI40Mhz = (uint8_t) pBeacon->HTCaps.shortGI40MHz;
190 pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor;
191 pPeer->htSecondaryChannelOffset =
192 pBeacon->HTInfo.secondaryChannelOffset;
193 pPeer->htLdpcCapable = (uint8_t) pBeacon->HTCaps.advCodingCap;
194 }
195
196 /* Collect peer VHT capabilities based on the received beacon from the peer */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197 if (pBeacon->VHTCaps.present) {
198 pPeer->vhtSupportedChannelWidthSet =
199 pBeacon->VHTOperation.chanWidth;
200 pPeer->vhtCapable = pBeacon->VHTCaps.present;
201
202 /* Collect VHT capabilities from beacon */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530203 qdf_mem_copy((uint8_t *) &pPeer->VHTCaps,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800204 (uint8_t *) &pBeacon->VHTCaps,
205 sizeof(tDot11fIEVHTCaps));
206 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800207 pPeer->erpIePresent = pBeacon->erpPresent;
208
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530209 qdf_mem_copy((uint8_t *) &pPeer->supportedRates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210 (uint8_t *) &pBeacon->supportedRates,
211 pBeacon->supportedRates.numRates + 1);
212 if (pPeer->extendedRatesPresent)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530213 qdf_mem_copy((uint8_t *) &pPeer->extendedRates,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800214 (uint8_t *) &pBeacon->extendedRates,
215 pBeacon->extendedRates.numRates + 1);
216 else
217 pPeer->extendedRates.numRates = 0;
218
219 pPeer->next = NULL;
220} /*** end ibss_peer_collect() ***/
221
222/* handle change in peer qos/wme capabilities */
223static void
224ibss_sta_caps_update(tpAniSirGlobal pMac,
225 tLimIbssPeerNode *pPeerNode, tpPESession psessionEntry)
226{
227 uint16_t peerIdx;
228 tpDphHashNode pStaDs;
229
230 pPeerNode->beaconHBCount++; /* Update beacon count. */
231
232 /* if the peer node exists, update its qos capabilities */
233 pStaDs = dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
234 &psessionEntry->dph.dphHashTable);
235 if (pStaDs == NULL)
236 return;
237
238 /* Update HT Capabilities */
239 if (IS_DOT11_MODE_HT(psessionEntry->dot11mode)) {
240 pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable;
241 if (pPeerNode->htCapable) {
242 pStaDs->htGreenfield = pPeerNode->htGreenfield;
243 pStaDs->htSupportedChannelWidthSet =
244 pPeerNode->htSupportedChannelWidthSet;
Abhishek Singh10a00262015-10-16 16:26:14 +0530245 pStaDs->htSecondaryChannelOffset =
246 pPeerNode->htSecondaryChannelOffset;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800247 pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState;
248 pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength;
249 pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity;
250 pStaDs->htDsssCckRate40MHzSupport =
251 pPeerNode->htDsssCckRate40MHzSupport;
252 pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz;
253 pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz;
254 pStaDs->htMaxRxAMpduFactor =
255 pPeerNode->htMaxRxAMpduFactor;
256 /* In the future, may need to check for "delayedBA" */
257 /* For now, it is IMMEDIATE BA only on ALL TID's */
258 pStaDs->baPolicyFlag = 0xFF;
259 pStaDs->htLdpcCapable = pPeerNode->htLdpcCapable;
260 }
261 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 if (IS_DOT11_MODE_VHT(psessionEntry->dot11mode)) {
263 pStaDs->mlmStaContext.vhtCapability = pPeerNode->vhtCapable;
264 if (pPeerNode->vhtCapable) {
265 pStaDs->vhtSupportedChannelWidthSet =
266 pPeerNode->vhtSupportedChannelWidthSet;
267
268 /* If in 11AC mode and if session requires 11AC mode, consider peer's */
269 /* max AMPDU length factor */
270 pStaDs->htMaxRxAMpduFactor =
271 pPeerNode->VHTCaps.maxAMPDULenExp;
272 pStaDs->vhtLdpcCapable =
273 (uint8_t) pPeerNode->VHTCaps.ldpcCodingCap;
274 }
275 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 /* peer is 11e capable but is not 11e enabled yet */
277 /* some STA's when joining Airgo IBSS, assert qos capability even when */
278 /* they don't suport qos. however, they do not include the edca parameter */
279 /* set. so let's check for edcaParam in addition to the qos capability */
280 if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled)
281 && pPeerNode->edcaPresent) {
282 pStaDs->qosMode = 1;
283 pStaDs->wmeEnabled = 0;
284 if (!pStaDs->lleEnabled) {
285 pStaDs->lleEnabled = 1;
286 /* dphSetACM(pMac, pStaDs); */
287 }
288 return;
289 }
290 /* peer is not 11e capable now but was 11e enabled earlier */
291 else if (pStaDs->lleEnabled) {
292 pStaDs->qosMode = 0;
293 pStaDs->lleEnabled = 0;
294 }
295 /* peer is wme capable but is not wme enabled yet */
296 if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled) {
297 pStaDs->qosMode = 1;
298 pStaDs->lleEnabled = 0;
299 if (!pStaDs->wmeEnabled) {
300 pStaDs->wmeEnabled = 1;
301 }
302 return;
303 }
304 /* When the peer device supports EDCA parameters, then we were not
305 considering. Added this code when we saw that one of the Peer Device
306 was advertising WMM param where we were not honouring that. CR# 210756
307 */
308 if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) {
309 pStaDs->qosMode = 1;
310 pStaDs->lleEnabled = 0;
311 if (!pStaDs->wmeEnabled) {
312 pStaDs->wmeEnabled = 1;
313 }
314 return;
315 }
316 /* peer is not wme capable now but was wme enabled earlier */
317 else if (pStaDs->wmeEnabled) {
318 pStaDs->qosMode = 0;
319 pStaDs->wmeEnabled = 0;
320 }
321
322}
323
324static void
325ibss_sta_rates_update(tpAniSirGlobal pMac,
326 tpDphHashNode pStaDs,
327 tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
328{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800329 lim_populate_matching_rate_set(pMac, pStaDs, &pPeer->supportedRates,
330 &pPeer->extendedRates,
331 pPeer->supportedMCSSet, psessionEntry,
Krishna Kumaar Natarajand1cd56e2016-09-30 08:43:03 -0700332 &pPeer->VHTCaps, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333 pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
334} /*** end ibss_sta_info_update() ***/
335
336/**
337 * ibss_sta_info_update
338 *
339 ***FUNCTION:
340 * This is called to program both SW & Polaris context
341 * for peer in IBSS.
342 *
343 ***LOGIC:
344 *
345 ***ASSUMPTIONS:
346 *
347 ***NOTE:
348 *
349 * @param pMac - Pointer to Global MAC structure
350 * @param pStaDs - Pointer to DPH node
351 * @param pPeer - Pointer to IBSS peer node
352 *
353 * @return None
354 */
355
356static void
357ibss_sta_info_update(tpAniSirGlobal pMac,
358 tpDphHashNode pStaDs,
359 tLimIbssPeerNode *pPeer, tpPESession psessionEntry)
360{
361 pStaDs->staType = STA_ENTRY_PEER;
362 ibss_sta_caps_update(pMac, pPeer, psessionEntry);
363 ibss_sta_rates_update(pMac, pStaDs, pPeer, psessionEntry);
364} /*** end ibss_sta_info_update() ***/
365
366static void ibss_coalesce_free(tpAniSirGlobal pMac)
367{
368 if (pMac->lim.ibssInfo.pHdr != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530369 qdf_mem_free(pMac->lim.ibssInfo.pHdr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800370 if (pMac->lim.ibssInfo.pBeacon != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530371 qdf_mem_free(pMac->lim.ibssInfo.pBeacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800372
373 pMac->lim.ibssInfo.pHdr = NULL;
374 pMac->lim.ibssInfo.pBeacon = NULL;
375}
376
377/*
378 * save the beacon params for use when adding the bss
379 */
380static void
381ibss_coalesce_save(tpAniSirGlobal pMac,
382 tpSirMacMgmtHdr pHdr, tpSchBeaconStruct pBeacon)
383{
384 /* get rid of any saved info */
385 ibss_coalesce_free(pMac);
386
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530387 pMac->lim.ibssInfo.pHdr = qdf_mem_malloc(sizeof(*pHdr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800388 if (NULL == pMac->lim.ibssInfo.pHdr) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530389 pe_err("ibbs-save: Failed malloc pHdr");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800390 return;
391 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530392 pMac->lim.ibssInfo.pBeacon = qdf_mem_malloc(sizeof(*pBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393 if (NULL == pMac->lim.ibssInfo.pBeacon) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530394 pe_err("ibbs-save: Failed malloc pBeacon");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800395 ibss_coalesce_free(pMac);
396 return;
397 }
398
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530399 qdf_mem_copy(pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr));
400 qdf_mem_copy(pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800401}
402
403/*
404 * tries to add a new entry to dph hash node
405 * if necessary, an existing entry is eliminated
406 */
407static tSirRetStatus
408ibss_dph_entry_add(tpAniSirGlobal pMac,
409 tSirMacAddr peerAddr,
410 tpDphHashNode *ppSta, tpPESession psessionEntry)
411{
412 uint16_t peerIdx;
413 tpDphHashNode pStaDs;
414
415 *ppSta = NULL;
416
417 pStaDs =
418 dph_lookup_hash_entry(pMac, peerAddr, &peerIdx,
419 &psessionEntry->dph.dphHashTable);
420 if (pStaDs != NULL) {
421 /* Trying to add context for already existing STA in IBSS */
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530422 pe_err("STA exists already");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423 lim_print_mac_addr(pMac, peerAddr, LOGE);
424 return eSIR_FAILURE;
425 }
426
427 /**
428 * Assign an AID, delete context existing with that
429 * AID and then add an entry to hash table maintained
430 * by DPH module.
431 */
432 peerIdx = lim_assign_peer_idx(pMac, psessionEntry);
433
434 pStaDs =
435 dph_get_hash_entry(pMac, peerIdx, &psessionEntry->dph.dphHashTable);
436 if (pStaDs) {
437 (void)lim_del_sta(pMac, pStaDs, false /*asynchronous */,
438 psessionEntry);
439 lim_delete_dph_hash_entry(pMac, pStaDs->staAddr, peerIdx,
440 psessionEntry);
441 }
442
443 pStaDs =
444 dph_add_hash_entry(pMac, peerAddr, peerIdx,
445 &psessionEntry->dph.dphHashTable);
446 if (pStaDs == NULL) {
447 /* Could not add hash table entry */
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530448 pe_err("could not add hash entry at DPH for peerIdx/aid: %d MACaddr:",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800449 peerIdx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800450 lim_print_mac_addr(pMac, peerAddr, LOGE);
451 return eSIR_FAILURE;
452 }
453
454 *ppSta = pStaDs;
455 return eSIR_SUCCESS;
456}
457
458/* send a status change notification */
459static void
460ibss_status_chg_notify(tpAniSirGlobal pMac,
461 tSirMacAddr peerAddr,
462 uint16_t staIndex,
463 uint8_t ucastSig,
464 uint8_t bcastSig, uint16_t status, uint8_t sessionId)
465{
466
467 tLimIbssPeerNode *peerNode;
468 uint8_t *beacon = NULL;
469 uint16_t bcnLen = 0;
470
471 peerNode = ibss_peer_find(pMac, peerAddr);
472 if (peerNode != NULL) {
473 if (peerNode->beacon == NULL)
474 peerNode->beaconLen = 0;
475 beacon = peerNode->beacon;
476 bcnLen = peerNode->beaconLen;
477 peerNode->beacon = NULL;
478 peerNode->beaconLen = 0;
479 }
480
481 lim_send_sme_ibss_peer_ind(pMac, peerAddr, staIndex, ucastSig, bcastSig,
482 beacon, bcnLen, status, sessionId);
483
484 if (beacon != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530485 qdf_mem_free(beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800486 }
487}
488
489static void ibss_bss_add(tpAniSirGlobal pMac, tpPESession psessionEntry)
490{
491 tLimMlmStartReq mlmStartReq;
492 uint32_t cfg;
493 tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
494 tpSchBeaconStruct pBeacon =
495 (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
496 uint8_t numExtRates = 0;
497
498 if ((pHdr == NULL) || (pBeacon == NULL)) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530499 pe_err("Unable to add BSS (no cached BSS info)");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800500 return;
501 }
502
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530503 qdf_mem_copy(psessionEntry->bssId, pHdr->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800504
505 sir_copy_mac_addr(pHdr->bssId, psessionEntry->bssId);
506
507 /* Copy beacon interval from sessionTable */
508 cfg = psessionEntry->beaconParams.beaconInterval;
509 if (cfg != pBeacon->beaconInterval)
510 psessionEntry->beaconParams.beaconInterval =
511 pBeacon->beaconInterval;
512
513 /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to
514 * adapt to peer's capability with respect to short slot time. Changes have been made to lim_apply_configuration()
515 * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt
516 * to peer's short slot using code below.
517 */
518 /* If cfg is already set to current peer's capability then no need to set it again */
519 if (psessionEntry->shortSlotTimeSupported !=
520 pBeacon->capabilityInfo.shortSlotTime) {
521 psessionEntry->shortSlotTimeSupported =
522 pBeacon->capabilityInfo.shortSlotTime;
523 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530524 qdf_mem_copy((uint8_t *) &psessionEntry->pLimStartBssReq->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800525 operationalRateSet, (uint8_t *) &pBeacon->supportedRates,
526 pBeacon->supportedRates.numRates);
527
528 /**
529 * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when
530 * there is no extended rate IE present in beacon. This is especially important when
531 * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce.
532 * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to
533 * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile.
534 * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued.
535 * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12.
536 */
537
538 if (pBeacon->extendedRatesPresent)
539 numExtRates = pBeacon->extendedRates.numRates;
540 if (cfg_set_str(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
541 (uint8_t *) &pBeacon->extendedRates.rate,
542 numExtRates) != eSIR_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530543 pe_err("could not update ExtendedOperRateset at CFG");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 return;
545 }
546
547 /*
548 * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities
549 * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities
550 * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode
551 * even though all the nodes are capable of doing CB.
552 * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop.
553 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530554 qdf_mem_set((void *)&mlmStartReq, sizeof(mlmStartReq), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800555
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530556 qdf_mem_copy(mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557 mlmStartReq.rateSet.numRates =
558 psessionEntry->pLimStartBssReq->operationalRateSet.numRates;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530559 qdf_mem_copy(&mlmStartReq.rateSet.rate[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 &psessionEntry->pLimStartBssReq->operationalRateSet.
561 rate[0], mlmStartReq.rateSet.numRates);
562 mlmStartReq.bssType = eSIR_IBSS_MODE;
563 mlmStartReq.beaconPeriod = pBeacon->beaconInterval;
564 mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; /* psessionEntry->nwType is also OK???? */
565 mlmStartReq.htCapable = psessionEntry->htCapability;
566 mlmStartReq.htOperMode = pMac->lim.gHTOperMode;
567 mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection;
568 mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet;
569
570 /* reading the channel num from session Table */
571 mlmStartReq.channelNumber = psessionEntry->currentOperChannel;
572
573 mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode;
574
575 /* Copy the SSID for RxP filtering based on SSID. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530576 qdf_mem_copy((uint8_t *) &mlmStartReq.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 (uint8_t *) &psessionEntry->pLimStartBssReq->ssId,
578 psessionEntry->pLimStartBssReq->ssId.length + 1);
579
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530580 pe_debug("invoking ADD_BSS as part of coalescing!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800581 if (lim_mlm_add_bss(pMac, &mlmStartReq, psessionEntry) !=
582 eSIR_SME_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530583 pe_err("AddBss failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584 return;
585 }
586 /* Update fields in Beacon */
587 if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530588 pe_err("Unable to set fixed Beacon fields");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800589 return;
590 }
591
592}
593
594/* delete the current BSS */
595static void ibss_bss_delete(tpAniSirGlobal pMac, tpPESession psessionEntry)
596{
597 tSirRetStatus status;
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530598 pe_debug("Initiating IBSS Delete BSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800599 if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530600 pe_warn("Incorrect LIM MLM state for delBss: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800601 psessionEntry->limMlmState);
602 return;
603 }
604 status = lim_del_bss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
605 if (status != eSIR_SUCCESS)
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530606 pe_err("delBss failed for bss: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800607 psessionEntry->bssIdx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608}
609
610/**
611 * lim_ibss_init
612 *
613 ***FUNCTION:
614 * This function is called while starting an IBSS
615 * to initialize list used to maintain IBSS peers.
616 *
617 ***LOGIC:
618 *
619 ***ASSUMPTIONS:
620 *
621 ***NOTE:
622 *
623 * @param pMac - Pointer to Global MAC structure
624 * @return None
625 */
626
627void lim_ibss_init(tpAniSirGlobal pMac)
628{
629 pMac->lim.gLimIbssCoalescingHappened = 0;
630 pMac->lim.gLimIbssPeerList = NULL;
631 pMac->lim.gLimNumIbssPeers = 0;
632
633 /* ibss info - params for which ibss to join while coalescing */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530634 qdf_mem_set(&pMac->lim.ibssInfo, sizeof(tAniSirLimIbss), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635} /*** end lim_ibss_init() ***/
636
637/**
638 * lim_ibss_delete_all_peers
639 *
640 ***FUNCTION:
641 * This function is called to delete all peers.
642 *
643 ***LOGIC:
644 *
645 ***ASSUMPTIONS:
646 *
647 ***NOTE:
648 *
649 * @param pMac - Pointer to Global MAC structure
650 * @return None
651 */
652
Jeff Johnson5948a182016-10-06 18:47:06 -0700653static void lim_ibss_delete_all_peers(tpAniSirGlobal pMac,
654 tpPESession psessionEntry)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800655{
656 tLimIbssPeerNode *pCurrNode, *pTempNode;
657 tpDphHashNode pStaDs;
658 uint16_t peerIdx;
659
660 pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList;
661
662 while (pCurrNode != NULL) {
663 if (!pMac->lim.gLimNumIbssPeers) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530664 pe_err("Number of peers in the list is zero and node present");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800665 return;
666 }
667 /* Delete the dph entry for the station
668 * Since it is called to remove all peers, just delete from dph,
669 * no need to do any beacon related params i.e., dont call lim_delete_dph_hash_entry
670 */
671 pStaDs =
672 dph_lookup_hash_entry(pMac, pCurrNode->peerMacAddr, &peerIdx,
673 &psessionEntry->dph.dphHashTable);
674 if (pStaDs) {
675
676 ibss_status_chg_notify(pMac, pCurrNode->peerMacAddr,
677 pStaDs->staIndex,
678 pStaDs->ucUcastSig,
679 pStaDs->ucBcastSig,
680 eWNI_SME_IBSS_PEER_DEPARTED_IND,
681 psessionEntry->smeSessionId);
682 lim_release_peer_idx(pMac, peerIdx, psessionEntry);
683 dph_delete_hash_entry(pMac, pStaDs->staAddr, peerIdx,
684 &psessionEntry->dph.dphHashTable);
685 }
686
687 pTempNode = pCurrNode->next;
688
689 /* TODO :Sessionize this code */
690 /* Fix CR 227642: PeerList should point to the next node since the current node is being
691 * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this
692 * peer list to find the next peer. So this list needs to be updated with the no of peers left
693 * after each iteration in this while loop since one by one peers are deleted (freed) in this
694 * loop causing the lim.gLimIbssPeerList to point to some freed memory.
695 */
696 pMac->lim.gLimIbssPeerList = pTempNode;
697
698 if (pCurrNode->beacon) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530699 qdf_mem_free(pCurrNode->beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800700 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530701 qdf_mem_free(pCurrNode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702 if (pMac->lim.gLimNumIbssPeers > 0) /* be paranoid */
703 pMac->lim.gLimNumIbssPeers--;
704 pCurrNode = pTempNode;
705 }
706
707 if (pMac->lim.gLimNumIbssPeers)
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530708 pe_err("Number of peers: %d in the list is non-zero",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709 pMac->lim.gLimNumIbssPeers);
710
711 pMac->lim.gLimNumIbssPeers = 0;
712 pMac->lim.gLimIbssPeerList = NULL;
713
714}
715
716/**
717 * lim_ibss_delete() - This function is called while tearing down an IBSS
718 *
719 * @pMac: Pointer to Global MAC structure
720 * @psessionEntry: Pointer to session entry
721 *
722 * Return: none
723 */
724
725void lim_ibss_delete(tpAniSirGlobal pMac, tpPESession psessionEntry)
726{
727 lim_ibss_delete_all_peers(pMac, psessionEntry);
728 ibss_coalesce_free(pMac);
729}
730
731/** -------------------------------------------------------------
732 \fn lim_ibss_set_protection
733 \brief Decides all the protection related information.
734 \
735 \param tpAniSirGlobal pMac
736 \param tSirMacAddr peerMacAddr
737 \param tpUpdateBeaconParams pBeaconParams
738 \return None
739 -------------------------------------------------------------*/
740static void
741lim_ibss_set_protection(tpAniSirGlobal pMac, uint8_t enable,
742 tpUpdateBeaconParams pBeaconParams,
743 tpPESession psessionEntry)
744{
745
746 if (!pMac->lim.cfgProtection.fromllb) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530747 pe_err("protection from 11b is disabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800748 return;
749 }
750
751 if (enable) {
752 psessionEntry->gLim11bParams.protectionEnabled = true;
753 if (false ==
754 psessionEntry->beaconParams.
755 llbCoexist /*pMac->lim.llbCoexist */) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530756 pe_debug("=> IBSS: Enable Protection");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800757 pBeaconParams->llbCoexist =
758 psessionEntry->beaconParams.llbCoexist = true;
759 pBeaconParams->paramChangeBitmap |=
760 PARAM_llBCOEXIST_CHANGED;
761 }
762 } else if (true ==
763 psessionEntry->beaconParams.
764 llbCoexist /*pMac->lim.llbCoexist */) {
765 psessionEntry->gLim11bParams.protectionEnabled = false;
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530766 pe_debug("===> IBSS: Disable protection");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 pBeaconParams->llbCoexist =
768 psessionEntry->beaconParams.llbCoexist = false;
769 pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
770 }
771 return;
772}
773
774/** -------------------------------------------------------------
775 \fn lim_ibss_update_protection_params
776 \brief Decides all the protection related information.
777 \
778 \param tpAniSirGlobal pMac
779 \param tSirMacAddr peerMacAddr
780 \param tpUpdateBeaconParams pBeaconParams
781 \return None
782 -------------------------------------------------------------*/
783static void
784lim_ibss_update_protection_params(tpAniSirGlobal pMac,
785 tSirMacAddr peerMacAddr,
786 tLimProtStaCacheType protStaCacheType,
787 tpPESession psessionEntry)
788{
789 uint32_t i;
790
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530791 pe_debug("STA is associated Addr :");
Srinivas Girigowda8590a5f2017-03-10 14:28:37 -0800792 lim_print_mac_addr(pMac, peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793
794 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
795 if (pMac->lim.protStaCache[i].active) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530796 pe_debug("Addr:");
Srinivas Girigowda8590a5f2017-03-10 14:28:37 -0800797 lim_print_mac_addr
798 (pMac, pMac->lim.protStaCache[i].addr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530800 if (!qdf_mem_cmp(pMac->lim.protStaCache[i].addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 peerMacAddr,
802 sizeof(tSirMacAddr))) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530803 pe_debug("matching cache entry at: %d already active",
Srinivas Girigowda8590a5f2017-03-10 14:28:37 -0800804 i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800805 return;
806 }
807 }
808 }
809
810 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
811 if (!pMac->lim.protStaCache[i].active)
812 break;
813 }
814
815 if (i >= LIM_PROT_STA_CACHE_SIZE) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530816 pe_err("No space in ProtStaCache");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800817 return;
818 }
819
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530820 qdf_mem_copy(pMac->lim.protStaCache[i].addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821 peerMacAddr, sizeof(tSirMacAddr));
822
823 pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType;
824 pMac->lim.protStaCache[i].active = true;
825 if (eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType) {
826 psessionEntry->gLim11bParams.numSta++;
827 } else if (eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType) {
828 psessionEntry->gLim11gParams.numSta++;
829 }
830}
831
832/** -------------------------------------------------------------
833 \fn lim_ibss_decide_protection
834 \brief Decides all the protection related information.
835 \
836 \param tpAniSirGlobal pMac
837 \param tSirMacAddr peerMacAddr
838 \param tpUpdateBeaconParams pBeaconParams
839 \return None
840 -------------------------------------------------------------*/
841static void
842lim_ibss_decide_protection(tpAniSirGlobal pMac, tpDphHashNode pStaDs,
843 tpUpdateBeaconParams pBeaconParams,
844 tpPESession psessionEntry)
845{
846 tSirRFBand rfBand = SIR_BAND_UNKNOWN;
847 uint32_t phyMode;
848 tLimProtStaCacheType protStaCacheType =
849 eLIM_PROT_STA_CACHE_TYPE_INVALID;
850
851 pBeaconParams->paramChangeBitmap = 0;
852
853 if (NULL == pStaDs) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530854 pe_err("pStaDs is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800855 return;
856 }
857
858 lim_get_rf_band_new(pMac, &rfBand, psessionEntry);
859 if (SIR_BAND_2_4_GHZ == rfBand) {
860 lim_get_phy_mode(pMac, &phyMode, psessionEntry);
861
862 /* We are 11G or 11n. Check if we need protection from 11b Stations. */
863 if ((phyMode == WNI_CFG_PHY_MODE_11G)
864 || (psessionEntry->htCapability)) {
865 /* As we found in the past, it is possible that a 11n STA sends
866 * Beacon with HT IE but not ERP IE. So the absense of ERP IE
867 * in the Beacon is not enough to conclude that STA is 11b.
868 */
869 if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
870 (!pStaDs->mlmStaContext.htCapability)) {
871 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530872 pe_err("Enable protection from 11B");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800873 lim_ibss_set_protection(pMac, true,
874 pBeaconParams,
875 psessionEntry);
876 }
877 }
878 }
879 lim_ibss_update_protection_params(pMac, pStaDs->staAddr, protStaCacheType,
880 psessionEntry);
881 return;
882}
883
884/**
885 * lim_ibss_peer_find()
886 *
887 ***FUNCTION:
888 * This function is called while adding a context at
889 * DPH & Polaris for a peer in IBSS.
890 * If peer is found in the list, capabilities from the
891 * returned BSS description are used at DPH node & Polaris.
892 *
893 ***LOGIC:
894 *
895 ***ASSUMPTIONS:
896 *
897 ***NOTE:
898 *
899 * @param macAddr - MAC address of the peer
900 *
901 * @return Pointer to peer node if found, else NULL
902 */
903tLimIbssPeerNode *lim_ibss_peer_find(tpAniSirGlobal pMac, tSirMacAddr macAddr)
904{
905 return ibss_peer_find(pMac, macAddr);
906}
907
908/**
909 * lim_ibss_sta_add()
910 *
911 ***FUNCTION:
912 * This function is called to add an STA context in IBSS role
913 * whenever a data frame is received from/for a STA that failed
914 * hash lookup at DPH.
915 *
916 ***LOGIC:
917 *
918 ***ASSUMPTIONS:
919 * NA
920 *
921 ***NOTE:
922 * NA
923 *
924 * @param pMac Pointer to Global MAC structure
925 * @param peerAdddr MAC address of the peer being added
926 * @return retCode Indicates success or failure return code
927 * @return
928 */
929
930tSirRetStatus
931lim_ibss_sta_add(tpAniSirGlobal pMac, void *pBody, tpPESession psessionEntry)
932{
933 tSirRetStatus retCode = eSIR_SUCCESS;
934 tpDphHashNode pStaDs;
935 tLimIbssPeerNode *pPeerNode;
936 tLimMlmStates prevState;
937 tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody;
938 tUpdateBeaconParams beaconParams;
939
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530940 qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800941
942 if (pBody == 0) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530943 pe_err("Invalid IBSS AddSta");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944 return eSIR_FAILURE;
945 }
946
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530947 pe_debug("Rx Add-Ibss-Sta for MAC:");
Srinivas Girigowda8590a5f2017-03-10 14:28:37 -0800948 lim_print_mac_addr(pMac, *pPeerAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800949
950 pPeerNode = ibss_peer_find(pMac, *pPeerAddr);
951 if (NULL != pPeerNode) {
952 retCode =
953 ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs,
954 psessionEntry);
955 if (eSIR_SUCCESS == retCode) {
956 prevState = pStaDs->mlmStaContext.mlmState;
957 pStaDs->erpEnabled = pPeerNode->erpIePresent;
958
959 ibss_sta_info_update(pMac, pStaDs, pPeerNode,
960 psessionEntry);
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530961 pe_debug("initiating ADD STA for the IBSS peer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800962 retCode =
963 lim_add_sta(pMac, pStaDs, false, psessionEntry);
964 if (retCode != eSIR_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530965 pe_err("ibss-sta-add failed (reason %x)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800966 retCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967 lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
968 pStaDs->mlmStaContext.mlmState = prevState;
969 dph_delete_hash_entry(pMac, pStaDs->staAddr,
970 pStaDs->assocId,
971 &psessionEntry->dph.
972 dphHashTable);
973 } else {
974 if (pMac->lim.gLimProtectionControl !=
975 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
976 lim_ibss_decide_protection(pMac, pStaDs,
977 &beaconParams,
978 psessionEntry);
979
980 if (beaconParams.paramChangeBitmap) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530981 pe_debug("---> Update Beacon Params");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982 sch_set_fixed_beacon_fields(pMac,
983 psessionEntry);
984 beaconParams.bssIdx =
985 psessionEntry->bssIdx;
986 lim_send_beacon_params(pMac, &beaconParams,
987 psessionEntry);
988 }
989 }
990 } else {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +0530991 pe_err("hashTblAdd failed reason: %x", retCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800992 lim_print_mac_addr(pMac, *pPeerAddr, LOGE);
993 }
994 } else {
995 retCode = eSIR_FAILURE;
996 }
997
998 return retCode;
999}
Abhishek Singh3df76612017-05-16 14:05:32 +05301000
Abhishek Singh79e77502015-12-30 17:11:49 +05301001/**
Abhishek Singh3df76612017-05-16 14:05:32 +05301002 * lim_ibss_search_and_delete_peer()- to cleanup the IBSS
1003 * peer from lim ibss peer list
Abhishek Singh79e77502015-12-30 17:11:49 +05301004 *
1005 * @mac_ptr: Pointer to Global MAC structure
1006 * @session_entry: Session entry
1007 * @mac_addr: Mac Address of the IBSS peer
1008 *
Abhishek Singh3df76612017-05-16 14:05:32 +05301009 * This function is called to cleanup the IBSS peer from
1010 * lim ibss peer list
Abhishek Singh79e77502015-12-30 17:11:49 +05301011 *
1012 * Return: None
1013 *
1014 */
1015static void
Abhishek Singh3df76612017-05-16 14:05:32 +05301016lim_ibss_search_and_delete_peer(tpAniSirGlobal mac_ctx,
Abhishek Singh79e77502015-12-30 17:11:49 +05301017 tpPESession session_entry, tSirMacAddr mac_addr)
1018{
1019 tLimIbssPeerNode *temp_node, *prev_node;
1020 tLimIbssPeerNode *temp_next_node = NULL;
Abhishek Singh79e77502015-12-30 17:11:49 +05301021
Abhishek Singh3df76612017-05-16 14:05:32 +05301022 prev_node = temp_node = mac_ctx->lim.gLimIbssPeerList;
Abhishek Singh79e77502015-12-30 17:11:49 +05301023
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301024 pe_debug(" PEER ADDR :" MAC_ADDRESS_STR,
Abhishek Singh79e77502015-12-30 17:11:49 +05301025 MAC_ADDR_ARRAY(mac_addr));
1026
1027 /** Compare Peer */
1028 while (NULL != temp_node) {
1029 temp_next_node = temp_node->next;
1030
1031 /* Delete the STA with MAC address */
1032 if (!qdf_mem_cmp((uint8_t *) mac_addr,
1033 (uint8_t *) &temp_node->peerMacAddr,
1034 sizeof(tSirMacAddr))) {
Abhishek Singh3df76612017-05-16 14:05:32 +05301035 if (temp_node ==
1036 mac_ctx->lim.gLimIbssPeerList) {
1037 mac_ctx->lim.gLimIbssPeerList =
1038 temp_node->next;
1039 prev_node =
1040 mac_ctx->lim.gLimIbssPeerList;
1041 } else
1042 prev_node->next = temp_node->next;
1043 if (temp_node->beacon)
1044 qdf_mem_free(temp_node->beacon);
Abhishek Singh79e77502015-12-30 17:11:49 +05301045
Abhishek Singh3df76612017-05-16 14:05:32 +05301046 qdf_mem_free(temp_node);
1047 mac_ctx->lim.gLimNumIbssPeers--;
Abhishek Singh79e77502015-12-30 17:11:49 +05301048
Abhishek Singh3df76612017-05-16 14:05:32 +05301049 temp_node = temp_next_node;
1050 break;
Abhishek Singh79e77502015-12-30 17:11:49 +05301051 }
1052 prev_node = temp_node;
1053 temp_node = temp_next_node;
1054 }
1055 /*
1056 * if it is the last peer walking out, we better
1057 * we set IBSS state to inactive.
1058 */
Abhishek Singh3df76612017-05-16 14:05:32 +05301059 if (0 == mac_ctx->lim.gLimNumIbssPeers) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301060 pe_debug("Last STA from IBSS walked out");
Abhishek Singh79e77502015-12-30 17:11:49 +05301061 session_entry->limIbssActive = false;
1062 }
1063}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064
Abhishek Singh3df76612017-05-16 14:05:32 +05301065/**
1066 * lim_ibss_delete_peer()- to delete IBSS peer
1067 *
1068 * @mac_ptr: Pointer to Global MAC structure
1069 * @session_entry: Session entry
1070 * @mac_addr: Mac Address of the IBSS peer
1071 *
1072 * This function is called delete IBSS peer.
1073 *
1074 * Return: None
1075 *
1076 */
1077static void
1078lim_ibss_delete_peer(tpAniSirGlobal mac_ctx,
1079 tpPESession session_entry, tSirMacAddr mac_addr)
1080{
1081 tpDphHashNode sta = NULL;
1082 uint16_t peer_idx = 0;
1083
1084 pe_debug("Delete peer :" MAC_ADDRESS_STR,
1085 MAC_ADDR_ARRAY(mac_addr));
1086
1087 sta = dph_lookup_hash_entry(mac_ctx, mac_addr,
1088 &peer_idx,
1089 &session_entry->dph.
1090 dphHashTable);
1091
1092 if (!sta) {
1093 pe_err("DPH Entry for STA %pM is missing",
1094 mac_addr);
1095 return;
1096 }
1097
1098 if (STA_INVALID_IDX != sta->staIndex) {
1099 lim_del_sta(mac_ctx, sta,
1100 true, session_entry);
1101 } else {
1102 /*
1103 * This mean ADD STA failed, thus remove the sta from
1104 * from database and no need to send del sta to firmware
1105 * and peer departed indication to upper layer.
1106 */
1107 lim_delete_dph_hash_entry(mac_ctx, sta->staAddr,
1108 peer_idx, session_entry);
1109 lim_release_peer_idx(mac_ctx,
1110 peer_idx, session_entry);
1111 lim_ibss_search_and_delete_peer(mac_ctx,
1112 session_entry, mac_addr);
1113 }
1114
1115}
1116
1117void lim_process_ibss_del_sta_rsp(tpAniSirGlobal mac_ctx,
1118 struct scheduler_msg *lim_msg,
1119 tpPESession pe_session)
1120{
1121 tpDphHashNode sta_ds = NULL;
1122 tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
1123 tSirResultCodes status = eSIR_SME_SUCCESS;
1124
1125 if (!del_sta_params) {
1126 pe_err("del_sta_params is NULL");
1127 return;
1128 }
1129 if (!LIM_IS_IBSS_ROLE(pe_session)) {
1130 pe_err("Session %d is not IBSS role", del_sta_params->assocId);
1131 status = eSIR_SME_REFUSED;
1132 goto skip_event;
1133 }
1134
1135 sta_ds = dph_get_hash_entry(mac_ctx, del_sta_params->assocId,
1136 &pe_session->dph.dphHashTable);
1137 if (!sta_ds) {
1138 pe_err("DPH Entry for STA %X is missing",
1139 del_sta_params->assocId);
1140 status = eSIR_SME_REFUSED;
1141 goto skip_event;
1142 }
1143
1144 if (QDF_STATUS_SUCCESS != del_sta_params->status) {
1145 pe_err("DEL STA failed!");
1146 status = eSIR_SME_REFUSED;
1147 goto skip_event;
1148 }
1149 pe_debug("Deleted STA associd %d staId %d MAC " MAC_ADDRESS_STR,
1150 sta_ds->assocId, sta_ds->staIndex,
1151 MAC_ADDR_ARRAY(sta_ds->staAddr));
1152
1153 lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr,
1154 del_sta_params->assocId, pe_session);
1155 lim_release_peer_idx(mac_ctx,
1156 del_sta_params->assocId, pe_session);
1157
1158 ibss_status_chg_notify(mac_ctx,
1159 del_sta_params->staMac,
1160 sta_ds->staIndex,
1161 sta_ds->ucUcastSig, sta_ds->ucBcastSig,
1162 eWNI_SME_IBSS_PEER_DEPARTED_IND,
1163 pe_session->smeSessionId);
1164
1165 lim_ibss_search_and_delete_peer(mac_ctx,
1166 pe_session, del_sta_params->staMac);
1167
1168skip_event:
1169 qdf_mem_free(del_sta_params);
1170 lim_msg->bodyptr = NULL;
1171}
1172
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001173/* handle the response from HAL for an ADD STA request */
1174tSirRetStatus
1175lim_ibss_add_sta_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
1176{
1177 tpDphHashNode pStaDs;
1178 uint16_t peerIdx;
1179 tpAddStaParams pAddStaParams = (tpAddStaParams) msg;
1180
1181 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1182 if (pAddStaParams == NULL) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301183 pe_err("IBSS: ADD_STA_RSP with no body!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001184 return eSIR_FAILURE;
1185 }
1186
1187 pStaDs =
1188 dph_lookup_hash_entry(pMac, pAddStaParams->staMac, &peerIdx,
1189 &psessionEntry->dph.dphHashTable);
1190 if (pStaDs == NULL) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301191 pe_err("IBSS: ADD_STA_RSP for unknown MAC addr: "MAC_ADDRESS_STR,
Abhishek Singh79e77502015-12-30 17:11:49 +05301192 MAC_ADDR_ARRAY(pAddStaParams->staMac));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301193 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001194 return eSIR_FAILURE;
1195 }
1196
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301197 if (pAddStaParams->status != QDF_STATUS_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301198 pe_err("IBSS: ADD_STA_RSP error: %x for MAC:"MAC_ADDRESS_STR,
Abhishek Singh79e77502015-12-30 17:11:49 +05301199 pAddStaParams->status,
1200 MAC_ADDR_ARRAY(pAddStaParams->staMac));
Abhishek Singh3df76612017-05-16 14:05:32 +05301201 lim_ibss_delete_peer(pMac,
Abhishek Singh79e77502015-12-30 17:11:49 +05301202 psessionEntry, pAddStaParams->staMac);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301203 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204 return eSIR_FAILURE;
1205 }
1206
1207 pStaDs->bssId = pAddStaParams->bssIdx;
1208 pStaDs->staIndex = pAddStaParams->staIdx;
1209 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
1210 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
1211 pStaDs->valid = 1;
1212 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
1213
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301214 pe_debug("IBSS: sending IBSS_NEW_PEER msg to SME!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215
1216 ibss_status_chg_notify(pMac, pAddStaParams->staMac,
1217 pStaDs->staIndex, pStaDs->ucUcastSig,
1218 pStaDs->ucBcastSig,
1219 eWNI_SME_IBSS_NEW_PEER_IND,
1220 psessionEntry->smeSessionId);
1221
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301222 qdf_mem_free(pAddStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001223
1224 return eSIR_SUCCESS;
1225}
1226
1227void lim_ibss_del_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
1228 tpPESession psessionEntry)
1229{
1230 tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
1231
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301232 pe_debug("IBSS: DEL_BSS_RSP Rcvd during coalescing!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233
1234 if (pDelBss == NULL) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301235 pe_err("IBSS: DEL_BSS_RSP(coalesce) with no body!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 goto end;
1237 }
1238
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301239 if (pDelBss->status != QDF_STATUS_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301240 pe_err("IBSS: DEL_BSS_RSP(coalesce) error: %x Bss: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001241 pDelBss->status, pDelBss->bssIdx);
1242 goto end;
1243 }
1244 /* Delete peer entries. */
1245 lim_ibss_delete_all_peers(pMac, psessionEntry);
1246
1247 /* add the new bss */
1248 ibss_bss_add(pMac, psessionEntry);
1249
1250end:
1251 if (pDelBss != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301252 qdf_mem_free(pDelBss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253}
1254
1255void lim_ibss_add_bss_rsp_when_coalescing(tpAniSirGlobal pMac, void *msg,
1256 tpPESession pSessionEntry)
1257{
1258 uint8_t infoLen;
1259 tSirSmeNewBssInfo newBssInfo;
1260
1261 tpAddBssParams pAddBss = (tpAddBssParams) msg;
1262
1263 tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
1264 tpSchBeaconStruct pBeacon =
1265 (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
1266
1267 if ((pHdr == NULL) || (pBeacon == NULL)) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301268 pe_err("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001269 goto end;
1270 }
1271 /* Inform Host of IBSS coalescing */
1272 infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) +
1273 sizeof(uint8_t) + pBeacon->ssId.length + 1;
1274
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301275 qdf_mem_set((void *)&newBssInfo, sizeof(newBssInfo), 0);
1276 qdf_mem_copy(newBssInfo.bssId.bytes, pHdr->bssId, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277 newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301278 qdf_mem_copy((uint8_t *) &newBssInfo.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 (uint8_t *) &pBeacon->ssId, pBeacon->ssId.length + 1);
1280
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301281 pe_debug("Sending JOINED_NEW_BSS notification to SME");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282
1283 lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_JOINED_NEW_BSS,
1284 (uint32_t *) &newBssInfo,
1285 infoLen, pSessionEntry->smeSessionId);
1286 {
1287 /* Configure beacon and send beacons to HAL */
1288 lim_send_beacon_ind(pMac, pSessionEntry);
1289 }
1290
1291end:
1292 ibss_coalesce_free(pMac);
1293}
1294
1295void lim_ibss_del_bss_rsp(tpAniSirGlobal pMac, void *msg, tpPESession psessionEntry)
1296{
1297 tSirResultCodes rc = eSIR_SME_SUCCESS;
1298 tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
1299 tSirMacAddr nullBssid = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1300
1301 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1302 if (pDelBss == NULL) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301303 pe_err("IBSS: DEL_BSS_RSP with no body!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001304 rc = eSIR_SME_REFUSED;
1305 goto end;
1306 }
1307
1308 psessionEntry = pe_find_session_by_session_id(pMac, pDelBss->sessionId);
1309 if (psessionEntry == NULL) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301310 pe_err("Session Does not exist for given sessionID");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 goto end;
1312 }
1313
1314 /*
1315 * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true.
1316 * BSS has to be added again in this scenario, so this case needs to be handled separately.
1317 * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to
1318 * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME.
1319 */
1320 if (true == pMac->lim.gLimIbssCoalescingHappened) {
1321
1322 lim_ibss_del_bss_rsp_when_coalescing(pMac, msg, psessionEntry);
1323 return;
1324 }
1325
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301326 if (pDelBss->status != QDF_STATUS_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301327 pe_err("IBSS: DEL_BSS_RSP error: %x Bss: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001328 pDelBss->status, pDelBss->bssIdx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329 rc = eSIR_SME_STOP_BSS_FAILURE;
1330 goto end;
1331 }
1332
1333 if (lim_set_link_state(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
1334 psessionEntry->selfMacAddr, NULL,
1335 NULL) != eSIR_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301336 pe_err("IBSS: DEL_BSS_RSP setLinkState failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001337 rc = eSIR_SME_REFUSED;
1338 goto end;
1339 }
1340
1341 lim_ibss_delete(pMac, psessionEntry);
1342
1343 dph_hash_table_class_init(pMac, &psessionEntry->dph.dphHashTable);
1344 lim_delete_pre_auth_list(pMac);
1345
1346 psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
1347
1348 MTRACE(mac_trace
1349 (pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId,
1350 psessionEntry->limMlmState));
1351
1352 psessionEntry->limSystemRole = eLIM_STA_ROLE;
1353
1354 /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra
1355 * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from lim_apply_configuration
1356 */
1357 psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF;
1358
1359end:
1360 if (pDelBss != NULL)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301361 qdf_mem_free(pDelBss);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362 /* Delete PE session once BSS is deleted */
1363 if (NULL != psessionEntry) {
1364 lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,
1365 psessionEntry->smeSessionId,
1366 psessionEntry->transactionId);
1367 pe_delete_session(pMac, psessionEntry);
1368 psessionEntry = NULL;
1369 }
1370}
1371
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001372/**
1373 * lim_ibss_coalesce()
1374 *
1375 ***FUNCTION:
1376 * This function is called upon receiving Beacon/Probe Response
1377 * while operating in IBSS mode.
1378 *
1379 ***LOGIC:
1380 *
1381 ***ASSUMPTIONS:
1382 *
1383 ***NOTE:
1384 *
1385 * @param pMac - Pointer to Global MAC structure
1386 * @param pBeacon - Parsed Beacon Frame structure
1387 * @param pBD - Pointer to received BD
1388 *
1389 * @return Status whether to process or ignore received Beacon Frame
1390 */
1391
1392tSirRetStatus
1393lim_ibss_coalesce(tpAniSirGlobal pMac,
1394 tpSirMacMgmtHdr pHdr,
1395 tpSchBeaconStruct pBeacon,
1396 uint8_t *pIEs,
1397 uint32_t ieLen, uint16_t fTsfLater, tpPESession psessionEntry)
1398{
1399 uint16_t peerIdx;
1400 tSirMacAddr currentBssId;
1401 tLimIbssPeerNode *pPeerNode;
1402 tpDphHashNode pStaDs;
1403 tUpdateBeaconParams beaconParams;
1404
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301405 qdf_mem_set((uint8_t *) &beaconParams, sizeof(tUpdateBeaconParams), 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001406
1407 sir_copy_mac_addr(currentBssId, psessionEntry->bssId);
1408
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301409 pe_debug("Current BSSID :" MAC_ADDRESS_STR " Received BSSID :"
1410 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(currentBssId),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 MAC_ADDR_ARRAY(pHdr->bssId));
1412
1413 /* Check for IBSS Coalescing only if Beacon is from different BSS */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301414 if (qdf_mem_cmp(currentBssId, pHdr->bssId, sizeof(tSirMacAddr))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 && psessionEntry->isCoalesingInIBSSAllowed) {
1416 /*
1417 * If STA entry is already available in the LIM hash table, then it is
1418 * possible that the peer may have left and rejoined within the heartbeat
1419 * timeout. In the offloaded case with 32 peers, the HB timeout is whopping
1420 * 128 seconds. In that case, the FW will not let any frames come in until
1421 * atleast the last sequence number is received before the peer is left
1422 * Hence, if the coalescing peer is already there in the peer list and if
1423 * the BSSID matches then, invoke delSta() to cleanup the entries. We will
1424 * let the peer coalesce when we receive next beacon from the peer
1425 */
1426 pPeerNode = ibss_peer_find(pMac, pHdr->sa);
1427 if (NULL != pPeerNode) {
Abhishek Singh3df76612017-05-16 14:05:32 +05301428 lim_ibss_delete_peer(pMac, psessionEntry,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001429 pHdr->sa);
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301430 pe_warn("Peer attempting to reconnect before HB timeout, deleted");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431 return eSIR_LIM_IGNORE_BEACON;
1432 }
1433
1434 if (!fTsfLater) { /* No Coalescing happened. */
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301435 pe_warn("No Coalescing happened");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 return eSIR_LIM_IGNORE_BEACON;
1437 }
1438 /*
1439 * IBSS Coalescing happened.
1440 * save the received beacon, and delete the current BSS. The rest of the
1441 * processing will be done in the delBss response processing
1442 */
1443 pMac->lim.gLimIbssCoalescingHappened = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001444 ibss_coalesce_save(pMac, pHdr, pBeacon);
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301445 pe_debug("IBSS Coalescing happened Delete BSSID :" MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 MAC_ADDR_ARRAY(currentBssId));
1447 ibss_bss_delete(pMac, psessionEntry);
1448 return eSIR_SUCCESS;
1449 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301450 if (qdf_mem_cmp
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451 (currentBssId, pHdr->bssId, sizeof(tSirMacAddr)))
1452 return eSIR_LIM_IGNORE_BEACON;
1453 }
1454
1455 /* STA in IBSS mode and SSID matches with ours */
1456 pPeerNode = ibss_peer_find(pMac, pHdr->sa);
1457 if (pPeerNode == NULL) {
1458 /* Peer not in the list - Collect BSS description & add to the list */
1459 uint32_t frameLen;
1460 tSirRetStatus retCode;
1461
1462 /*
1463 * Limit the Max number of IBSS Peers allowed as the max
1464 * number of STA's allowed
1465 * pMac->lim.gLimNumIbssPeers will be increamented after exiting
1466 * this function. so we will add additional 1 to compare against
1467 * pMac->lim.gLimIbssStaLimit
1468 */
1469 if ((pMac->lim.gLimNumIbssPeers + 1) >=
1470 pMac->lim.gLimIbssStaLimit) {
1471 /*Print every 100th time */
1472 if (pMac->lim.ibss_retry_cnt % 100 == 0) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301473 pe_debug("**** MAX STA LIMIT HAS REACHED ****");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 }
1475 pMac->lim.ibss_retry_cnt++;
1476 return eSIR_LIM_MAX_STA_REACHED_ERROR;
1477 }
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301478 pe_debug("IBSS Peer node does not exist, adding it");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001479 frameLen =
1480 sizeof(tLimIbssPeerNode) + ieLen - sizeof(uint32_t);
1481
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301482 pPeerNode = qdf_mem_malloc((uint16_t) frameLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001483 if (NULL == pPeerNode) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301484 pe_err("alloc fail %d bytes storing IBSS peer info",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001485 frameLen);
1486 return eSIR_MEM_ALLOC_FAILED;
1487 }
1488
1489 pPeerNode->beacon = NULL;
1490 pPeerNode->beaconLen = 0;
1491
1492 ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,
1493 psessionEntry);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301494 pPeerNode->beacon = qdf_mem_malloc(ieLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001495 if (NULL == pPeerNode->beacon) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301496 pe_err("Unable to allocate memory to store beacon");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001497 } else {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301498 qdf_mem_copy(pPeerNode->beacon, pIEs, ieLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001499 pPeerNode->beaconLen = (uint16_t) ieLen;
1500 }
1501 ibss_peer_add(pMac, pPeerNode);
1502
1503 pStaDs =
1504 dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
1505 &psessionEntry->dph.dphHashTable);
1506 if (pStaDs != NULL) {
1507 /* / DPH node already exists for the peer */
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301508 pe_warn("DPH Node present for just learned peer");
Srinivas Girigowda8590a5f2017-03-10 14:28:37 -08001509 lim_print_mac_addr(pMac, pPeerNode->peerMacAddr, LOGD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510 ibss_sta_info_update(pMac, pStaDs, pPeerNode,
1511 psessionEntry);
1512 return eSIR_SUCCESS;
1513 }
1514 retCode =
1515 lim_ibss_sta_add(pMac, pPeerNode->peerMacAddr, psessionEntry);
1516 if (retCode != eSIR_SUCCESS) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301517 pe_err("lim-ibss-sta-add failed reason: %x", retCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518 lim_print_mac_addr(pMac, pPeerNode->peerMacAddr, LOGE);
1519 return retCode;
1520 }
1521 /* Decide protection mode */
1522 pStaDs =
1523 dph_lookup_hash_entry(pMac, pPeerNode->peerMacAddr, &peerIdx,
1524 &psessionEntry->dph.dphHashTable);
1525 if (pMac->lim.gLimProtectionControl !=
1526 WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
1527 lim_ibss_decide_protection(pMac, pStaDs, &beaconParams,
1528 psessionEntry);
1529
1530 if (beaconParams.paramChangeBitmap) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301531 pe_err("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 sch_set_fixed_beacon_fields(pMac, psessionEntry);
1533 beaconParams.bssIdx = psessionEntry->bssIdx;
1534 lim_send_beacon_params(pMac, &beaconParams, psessionEntry);
1535 }
1536 } else
1537 ibss_sta_caps_update(pMac, pPeerNode, psessionEntry);
1538
1539 if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
1540 return eSIR_SUCCESS;
1541
1542 /* Received Beacon from same IBSS we're */
1543 /* currently part of. Inform Roaming algorithm */
1544 /* if not already that IBSS is active. */
1545 if (psessionEntry->limIbssActive == false) {
1546 limResetHBPktCount(psessionEntry);
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301547 pe_warn("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548 psessionEntry->limIbssActive = true;
1549 lim_send_sme_wm_status_change_ntf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0,
1550 psessionEntry->smeSessionId);
1551 }
1552
1553 return eSIR_SUCCESS;
1554} /*** end lim_handle_ibs_scoalescing() ***/
1555
1556/**
1557 * lim_ibss_heart_beat_handle() - handle IBSS hearbeat failure
1558 *
1559 * @mac_ctx: global mac context
1560 * @session: PE session entry
1561 *
1562 * Hanlde IBSS hearbeat failure.
1563 *
1564 * Return: None.
1565 */
1566void lim_ibss_heart_beat_handle(tpAniSirGlobal mac_ctx, tpPESession session)
1567{
1568 tLimIbssPeerNode *tempnode, *prevnode;
1569 tLimIbssPeerNode *temp_next = NULL;
1570 uint16_t peer_idx = 0;
1571 tpDphHashNode stads = 0;
1572 uint32_t threshold = 0;
1573 uint16_t sta_idx = 0;
1574 uint8_t ucast_sig = 0;
1575 uint8_t bcast_sig = 0;
1576
1577 /*
1578 * MLM BSS is started and if PE in scanmode then MLM state will be
1579 * waiting for probe resp. If Heart beat timeout triggers during this
1580 * corner case then we need to reactivate HeartBeat timer.
1581 */
1582 if (session->limMlmState != eLIM_MLM_BSS_STARTED_STATE)
1583 return;
1584
1585 /* If LinkMonitor is Disabled */
1586 if (!mac_ctx->sys.gSysEnableLinkMonitorMode)
1587 return;
1588
1589 prevnode = tempnode = mac_ctx->lim.gLimIbssPeerList;
1590 threshold = (mac_ctx->lim.gLimNumIbssPeers / 4) + 1;
1591
1592 /* Monitor the HeartBeat with the Individual PEERS in the IBSS */
1593 while (tempnode != NULL) {
1594 temp_next = tempnode->next;
1595 if (tempnode->beaconHBCount) {
1596 /* There was a beacon for this peer during heart beat */
1597 tempnode->beaconHBCount = 0;
1598 tempnode->heartbeatFailure = 0;
1599 prevnode = tempnode;
1600 tempnode = temp_next;
1601 continue;
1602 }
1603
1604 /* There wasnt any beacon received during heartbeat timer. */
1605 tempnode->heartbeatFailure++;
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301606 pe_err("Heartbeat fail: %d thres: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001607 tempnode->heartbeatFailure, mac_ctx->lim.gLimNumIbssPeers);
1608 if (tempnode->heartbeatFailure >= threshold) {
1609 /* Remove this entry from the list. */
1610 stads = dph_lookup_hash_entry(mac_ctx,
1611 tempnode->peerMacAddr, &peer_idx,
1612 &session->dph.dphHashTable);
1613 if (stads) {
1614 sta_idx = stads->staIndex;
1615 ucast_sig = stads->ucUcastSig;
1616 bcast_sig = stads->ucBcastSig;
1617
1618 (void)lim_del_sta(mac_ctx, stads, false,
1619 session);
1620 lim_delete_dph_hash_entry(mac_ctx,
1621 stads->staAddr, peer_idx, session);
1622 lim_release_peer_idx(mac_ctx, peer_idx,
1623 session);
1624 /* Send indication. */
1625 ibss_status_chg_notify(mac_ctx,
1626 tempnode->peerMacAddr, sta_idx,
1627 ucast_sig, bcast_sig,
1628 eWNI_SME_IBSS_PEER_DEPARTED_IND,
1629 session->smeSessionId);
1630 }
1631 if (tempnode == mac_ctx->lim.gLimIbssPeerList) {
1632 mac_ctx->lim.gLimIbssPeerList = tempnode->next;
1633 prevnode = mac_ctx->lim.gLimIbssPeerList;
1634 } else {
1635 prevnode->next = tempnode->next;
1636 }
1637
Kapil Guptac797b622016-10-18 12:05:44 +05301638 if (tempnode->beacon)
1639 qdf_mem_free(tempnode->beacon);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301640 qdf_mem_free(tempnode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641 mac_ctx->lim.gLimNumIbssPeers--;
1642
1643 /* we deleted current node, so prevNode remains same. */
1644 tempnode = temp_next;
1645 continue;
1646 }
1647 prevnode = tempnode;
1648 tempnode = temp_next;
1649 }
1650
1651 /*
1652 * General IBSS Activity Monitor,
1653 * check if in IBSS Mode we are received any Beacons
1654 */
1655 if (mac_ctx->lim.gLimNumIbssPeers) {
1656 if (session->LimRxedBeaconCntDuringHB <
1657 MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
1658 mac_ctx->lim.gLimHeartBeatBeaconStats[
1659 session->LimRxedBeaconCntDuringHB]++;
1660 else
1661 mac_ctx->lim.gLimHeartBeatBeaconStats[0]++;
1662
1663 /* Reset number of beacons received */
1664 limResetHBPktCount(session);
1665 return;
1666 } else {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301667 pe_warn("Heartbeat Failure");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 mac_ctx->lim.gLimHBfailureCntInLinkEstState++;
1669
1670 if (session->limIbssActive == true) {
1671 /*
1672 * We don't receive Beacon frames from any
1673 * other STA in IBSS. Announce IBSS inactive
1674 * to Roaming algorithm
1675 */
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301676 pe_warn("Alone in IBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677 session->limIbssActive = false;
1678
1679 lim_send_sme_wm_status_change_ntf(mac_ctx,
1680 eSIR_SME_IBSS_INACTIVE, NULL, 0,
1681 session->smeSessionId);
1682 }
1683 }
1684}
1685
1686/**
1687 * lim_ibss_decide_protection_on_delete() - decides protection related info.
1688 *
1689 * @mac_ctx: global mac context
1690 * @stads: station hash node
1691 * @bcn_param: beacon parameters
1692 * @session: PE session entry
1693 *
1694 * Decides all the protection related information.
1695 *
1696 * Return: None
1697 */
1698void lim_ibss_decide_protection_on_delete(tpAniSirGlobal mac_ctx,
1699 tpDphHashNode stads,
1700 tpUpdateBeaconParams bcn_param,
1701 tpPESession session)
1702{
1703 uint32_t phymode;
1704 tHalBitVal erpenabled = eHAL_CLEAR;
1705 tSirRFBand rfband = SIR_BAND_UNKNOWN;
1706 uint32_t i;
1707
1708 if (NULL == stads)
1709 return;
1710
1711 lim_get_rf_band_new(mac_ctx, &rfband, session);
1712 if (SIR_BAND_2_4_GHZ != rfband)
1713 return;
1714
1715 lim_get_phy_mode(mac_ctx, &phymode, session);
1716 erpenabled = stads->erpEnabled;
1717 /* we are HT or 11G and 11B station is getting deleted. */
1718 if (((phymode == WNI_CFG_PHY_MODE_11G) ||
1719 session->htCapability) && (erpenabled == eHAL_CLEAR)) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301720 pe_err("%d A legacy STA is disassociated Addr is",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 session->gLim11bParams.numSta);
1722 lim_print_mac_addr(mac_ctx, stads->staAddr, LOGE);
1723 if (session->gLim11bParams.numSta == 0) {
Nishank Aggarwale11ec7b2017-03-24 17:40:40 +05301724 pe_err("No 11B STA exists. Disable protection");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001725 lim_ibss_set_protection(mac_ctx, false,
1726 bcn_param, session);
1727 }
1728
1729 for (i = 0; i < LIM_PROT_STA_CACHE_SIZE; i++) {
1730 if (!mac_ctx->lim.protStaCache[i].active)
1731 continue;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301732 if (!qdf_mem_cmp(mac_ctx->lim.protStaCache[i].addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001733 stads->staAddr, sizeof(tSirMacAddr))) {
1734 session->gLim11bParams.numSta--;
1735 mac_ctx->lim.protStaCache[i].active = false;
1736 break;
1737 }
1738 }
1739
1740 }
1741}
1742
1743/** -----------------------------------------------------------------
1744 \fn __lim_ibss_peer_inactivity_handler
1745 \brief Internal function. Deletes FW indicated peer which is inactive
1746 \
1747 \param tpAniSirGlobal pMac
1748 \param tpPESession psessionEntry
1749 \param tpSirIbssPeerInactivityInd peerInactivityInd
1750 \return None
1751 -----------------------------------------------------------------*/
1752static void
1753__lim_ibss_peer_inactivity_handler(tpAniSirGlobal pMac,
1754 tpPESession psessionEntry,
1755 tpSirIbssPeerInactivityInd peerInactivityInd)
1756{
1757 if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
1758 return;
1759 }
1760
1761 /* delete the peer for which heartbeat is observed */
Abhishek Singh3df76612017-05-16 14:05:32 +05301762 lim_ibss_delete_peer(pMac, psessionEntry,
Srinivas Girigowda01d1c3c2015-11-25 16:54:41 -08001763 peerInactivityInd->peer_addr.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764}
1765
1766/** -------------------------------------------------------------
1767 \fn lim_process_ibss_peer_inactivity
1768 \brief Peer inactivity message handler
1769 \
1770 \param tpAniSirGlobal pMac
1771 \param void* buf
1772 \return None
1773 -------------------------------------------------------------*/
1774void lim_process_ibss_peer_inactivity(tpAniSirGlobal pMac, void *buf)
1775{
1776 /*
1777 * --------------- HEARTBEAT OFFLOAD CASE ------------------
1778 * This message handler is executed when the firmware identifies
1779 * inactivity from one or more peer devices. We will come here
1780 * for every inactive peer device
1781 */
1782 uint8_t i;
1783
1784 tSirIbssPeerInactivityInd *peerInactivityInd =
1785 (tSirIbssPeerInactivityInd *) buf;
1786
1787 /*
1788 * If IBSS is not started or heartbeat offload is not enabled
1789 * we should not handle this request
1790 */
1791 if (eLIM_STA_IN_IBSS_ROLE != pMac->lim.gLimSystemRole &&
1792 !IS_IBSS_HEARTBEAT_OFFLOAD_FEATURE_ENABLE) {
1793 return;
1794 }
1795
1796 /** If LinkMonitor is Disabled */
1797 if (!pMac->sys.gSysEnableLinkMonitorMode) {
1798 return;
1799 }
1800
1801 for (i = 0; i < pMac->lim.maxBssId; i++) {
1802 if (true == pMac->lim.gpSession[i].valid &&
1803 eSIR_IBSS_MODE == pMac->lim.gpSession[i].bssType) {
1804 __lim_ibss_peer_inactivity_handler(pMac,
1805 &pMac->lim.gpSession[i],
1806 peerInactivityInd);
1807 break;
1808 }
1809 }
1810}