blob: d980ded1492aee40d29950d1d3a36d4905aee4e9 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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 * Airgo Networks, Inc proprietary. All rights reserved.
24 * This file limIbssPeerMgmt.cc contains the utility functions
25 * LIM uses to maintain peers in IBSS.
26 * Author: Chandra Modumudi
27 * Date: 03/12/04
28 * History:-
29 * Date Modified by Modification Information
30 * --------------------------------------------------------------------
31 */
32#include "palTypes.h"
33#include "aniGlobal.h"
34#include "sirCommon.h"
35#if (WNI_POLARIS_FW_PRODUCT == AP)
36#include "wniCfgAp.h"
37#else
38#include "wniCfgSta.h"
39#endif
40#include "limUtils.h"
41#include "limAssocUtils.h"
42#include "limStaHashApi.h"
43#include "schApi.h" // schSetFixedBeaconFields for IBSS coalesce
44#include "limSecurityUtils.h"
45#include "limSendMessages.h"
46#include "limSession.h"
47#include "limIbssPeerMgmt.h"
48
49
50/**
51 * ibss_peer_find
52 *
53 *FUNCTION:
54 * This function is called while adding a context at
55 * DPH & Polaris for a peer in IBSS.
56 * If peer is found in the list, capabilities from the
57 * returned BSS description are used at DPH node & Polaris.
58 *
59 *LOGIC:
60 *
61 *ASSUMPTIONS:
62 *
63 *NOTE:
64 *
65 * @param macAddr - MAC address of the peer
66 *
67 * @return Pointer to peer node if found, else NULL
68 */
69
70static tLimIbssPeerNode *
71ibss_peer_find(
72 tpAniSirGlobal pMac,
73 tSirMacAddr macAddr)
74{
75 tLimIbssPeerNode *pTempNode = pMac->lim.gLimIbssPeerList;
76
77 while (pTempNode != NULL)
78 {
79 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
80 (tANI_U8 *) &pTempNode->peerMacAddr,
81 sizeof(tSirMacAddr)) )
82 break;
83 pTempNode = pTempNode->next;
84 }
85 return pTempNode;
86} /*** end ibss_peer_find() ***/
87
88/**
89 * ibss_peer_add
90 *
91 *FUNCTION:
92 * This is called on a STA in IBSS upon receiving Beacon/
93 * Probe Response from a peer.
94 *
95 *LOGIC:
96 * Node is always added to the front of the list
97 *
98 *ASSUMPTIONS:
99 *
100 *NOTE:
101 *
102 * @param pMac - Pointer to Global MAC structure
103 * @param pPeerNode - Pointer to peer node to be added to the list.
104 *
105 * @return None
106 */
107
108static tSirRetStatus
109ibss_peer_add(tpAniSirGlobal pMac, tLimIbssPeerNode *pPeerNode)
110{
111#ifdef ANI_SIR_IBSS_PEER_CACHING
112 tANI_U32 numIbssPeers = (2 * pMac->lim.maxStation);
113
114 if (pMac->lim.gLimNumIbssPeers >= numIbssPeers)
115 {
116 /**
117 * Reached max number of peers to be maintained.
118 * Delete last entry & add new entry at the beginning.
119 */
120 tLimIbssPeerNode *pTemp, *pPrev;
121 pTemp = pPrev = pMac->lim.gLimIbssPeerList;
122 while (pTemp->next != NULL)
123 {
124 pPrev = pTemp;
125 pTemp = pTemp->next;
126 }
127 if(pTemp->beacon)
128 {
129 palFreeMemory(pMac->hHdd, pTemp->beacon);
130 }
131
132 palFreeMemory( pMac->hHdd, (tANI_U8 *) pTemp);
133 pPrev->next = NULL;
134 }
135 else
136#endif
137 pMac->lim.gLimNumIbssPeers++;
138
139 pPeerNode->next = pMac->lim.gLimIbssPeerList;
140 pMac->lim.gLimIbssPeerList = pPeerNode;
141
142 return eSIR_SUCCESS;
143
144} /*** end limAddIbssPeerToList() ***/
145
146/**
147 * ibss_peer_collect
148 *
149 *FUNCTION:
150 * This is called to collect IBSS peer information
151 * from received Beacon/Probe Response frame from it.
152 *
153 *LOGIC:
154 *
155 *ASSUMPTIONS:
156 *
157 *NOTE:
158 *
159 * @param pMac - Pointer to Global MAC structure
160 * @param pBeacon - Parsed Beacon Frame structure
161 * @param pBD - Pointer to received BD
162 * @param pPeer - Pointer to IBSS peer node
163 *
164 * @return None
165 */
166
167static void
168ibss_peer_collect(
169 tpAniSirGlobal pMac,
170 tpSchBeaconStruct pBeacon,
171 tpSirMacMgmtHdr pHdr,
172 tLimIbssPeerNode *pPeer,
173 tpPESession psessionEntry)
174{
175 palCopyMemory( pMac->hHdd, pPeer->peerMacAddr, pHdr->sa, sizeof(tSirMacAddr));
176
177 pPeer->capabilityInfo = pBeacon->capabilityInfo;
178 pPeer->extendedRatesPresent = pBeacon->extendedRatesPresent;
179 pPeer->edcaPresent = pBeacon->edcaPresent;
180 pPeer->wmeEdcaPresent = pBeacon->wmeEdcaPresent;
181 pPeer->wmeInfoPresent = pBeacon->wmeInfoPresent;
182
183 if(IS_DOT11_MODE_HT(psessionEntry->dot11mode) &&
184 (pBeacon->HTCaps.present))
185 {
186 pPeer->htCapable = pBeacon->HTCaps.present;
187 palCopyMemory(pMac->hHdd, (tANI_U8 *)pPeer->supportedMCSSet,
188 (tANI_U8 *)pBeacon->HTCaps.supportedMCSSet,
189 sizeof(pPeer->supportedMCSSet));
190 pPeer->htGreenfield = (tANI_U8)pBeacon->HTCaps.greenField;
191 pPeer->htSupportedChannelWidthSet = ( tANI_U8 ) pBeacon->HTCaps.supportedChannelWidthSet;
192 pPeer->htMIMOPSState = (tSirMacHTMIMOPowerSaveState)pBeacon->HTCaps.mimoPowerSave;
193 pPeer->htMaxAmsduLength = ( tANI_U8 ) pBeacon->HTCaps.maximalAMSDUsize;
194 pPeer->htAMpduDensity = pBeacon->HTCaps.mpduDensity;
195 pPeer->htDsssCckRate40MHzSupport = (tANI_U8)pBeacon->HTCaps.dsssCckMode40MHz;
196 pPeer->htShortGI20Mhz = (tANI_U8)pBeacon->HTCaps.shortGI20MHz;
197 pPeer->htShortGI40Mhz = (tANI_U8)pBeacon->HTCaps.shortGI40MHz;
198 pPeer->htMaxRxAMpduFactor = pBeacon->HTCaps.maxRxAMPDUFactor;
199 }
200
201 pPeer->erpIePresent = pBeacon->erpPresent;
202
203 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pPeer->supportedRates,
204 (tANI_U8 *) &pBeacon->supportedRates,
205 pBeacon->supportedRates.numRates + 1);
206 if (pPeer->extendedRatesPresent)
207 palCopyMemory( pMac->hHdd, (tANI_U8 *) &pPeer->extendedRates,
208 (tANI_U8 *) &pBeacon->extendedRates,
209 pBeacon->extendedRates.numRates + 1);
210 else
211 pPeer->extendedRates.numRates = 0;
212
213 // TBD copy EDCA parameters
214 // pPeer->edcaParams;
215
216 pPeer->next = NULL;
217} /*** end ibss_peer_collect() ***/
218
219// handle change in peer qos/wme capabilities
220static void
221ibss_sta_caps_update(
222 tpAniSirGlobal pMac,
223 tLimIbssPeerNode *pPeerNode,
224 tpPESession psessionEntry)
225{
226 tANI_U16 aid;
227 tpDphHashNode pStaDs;
228
229 pPeerNode->beaconHBCount++; //Update beacon count.
230
231 // if the peer node exists, update its qos capabilities
232 if ((pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable)) == NULL)
233 return;
234
235
236 //Update HT Capabilities
237 if(IS_DOT11_MODE_HT(psessionEntry->dot11mode))
238 {
239 pStaDs->mlmStaContext.htCapability = pPeerNode->htCapable;
240 if (pPeerNode->htCapable)
241 {
242 pStaDs->htGreenfield = pPeerNode->htGreenfield;
243 pStaDs->htSupportedChannelWidthSet = pPeerNode->htSupportedChannelWidthSet;
244 pStaDs->htMIMOPSState = pPeerNode->htMIMOPSState;
245 pStaDs->htMaxAmsduLength = pPeerNode->htMaxAmsduLength;
246 pStaDs->htAMpduDensity = pPeerNode->htAMpduDensity;
247 pStaDs->htDsssCckRate40MHzSupport = pPeerNode->htDsssCckRate40MHzSupport;
248 pStaDs->htShortGI20Mhz = pPeerNode->htShortGI20Mhz;
249 pStaDs->htShortGI40Mhz = pPeerNode->htShortGI40Mhz;
250 pStaDs->htMaxRxAMpduFactor = pPeerNode->htMaxRxAMpduFactor;
251 // In the future, may need to check for "delayedBA"
252 // For now, it is IMMEDIATE BA only on ALL TID's
253 pStaDs->baPolicyFlag = 0xFF;
254 }
255 }
256
257 if(IS_DOT11_MODE_PROPRIETARY(psessionEntry->dot11mode) &&
258 pPeerNode->aniIndicator)
259 {
260 pStaDs->aniPeer = pPeerNode->aniIndicator;
261 pStaDs->propCapability = pPeerNode->propCapability;
262 }
263
264
265 // peer is 11e capable but is not 11e enabled yet
266 // some STA's when joining Airgo IBSS, assert qos capability even when
267 // they don't suport qos. however, they do not include the edca parameter
268 // set. so let's check for edcaParam in addition to the qos capability
269 if (pPeerNode->capabilityInfo.qos && (psessionEntry->limQosEnabled) && pPeerNode->edcaPresent)
270 {
271 pStaDs->qosMode = 1;
272 pStaDs->wmeEnabled = 0;
273 if (! pStaDs->lleEnabled)
274 {
275 pStaDs->lleEnabled = 1;
276 //dphSetACM(pMac, pStaDs);
277 }
278 return;
279 }
280 // peer is not 11e capable now but was 11e enabled earlier
281 else if (pStaDs->lleEnabled)
282 {
283 pStaDs->qosMode = 0;
284 pStaDs->lleEnabled = 0;
285 }
286
287 // peer is wme capable but is not wme enabled yet
288 if (pPeerNode->wmeInfoPresent && psessionEntry->limWmeEnabled)
289 {
290 pStaDs->qosMode = 1;
291 pStaDs->lleEnabled = 0;
292 if (! pStaDs->wmeEnabled)
293 {
294 pStaDs->wmeEnabled = 1;
295 //dphSetACM(pMac, pStaDs);
296 }
297 return;
298 }
299 /* When the peer device supports EDCA parameters, then we were not
300 considering. Added this code when we saw that one of the Peer Device
301 was advertising WMM param where we were not honouring that. CR# 210756
302 */
303 if (pPeerNode->wmeEdcaPresent && psessionEntry->limWmeEnabled) {
304 pStaDs->qosMode = 1;
305 pStaDs->lleEnabled = 0;
306 if (! pStaDs->wmeEnabled) {
307 pStaDs->wmeEnabled = 1;
308 }
309 return;
310 }
311
312 // peer is not wme capable now but was wme enabled earlier
313 else if (pStaDs->wmeEnabled)
314 {
315 pStaDs->qosMode = 0;
316 pStaDs->wmeEnabled = 0;
317 }
318
319}
320
321static void
322ibss_sta_rates_update(
323 tpAniSirGlobal pMac,
324 tpDphHashNode pStaDs,
325 tLimIbssPeerNode *pPeer,
326 tpPESession psessionEntry)
327{
Jeff Johnsone7245742012-09-05 17:12:55 -0700328#ifdef WLAN_FEATURE_11AC
329 limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates,
330 &pPeer->extendedRates, pPeer->supportedMCSSet,
331 &pStaDs->mlmStaContext.propRateSet,psessionEntry,NULL);
332#else
Jeff Johnson295189b2012-06-20 16:38:30 -0700333 // Populate supported rateset
334 limPopulateMatchingRateSet(pMac, pStaDs, &pPeer->supportedRates,
335 &pPeer->extendedRates, pPeer->supportedMCSSet,
336 &pStaDs->mlmStaContext.propRateSet,psessionEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -0700337#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700338
339 pStaDs->mlmStaContext.capabilityInfo = pPeer->capabilityInfo;
340} /*** end ibss_sta_info_update() ***/
341
342/**
343 * ibss_sta_info_update
344 *
345 *FUNCTION:
346 * This is called to program both SW & Polaris context
347 * for peer in IBSS.
348 *
349 *LOGIC:
350 *
351 *ASSUMPTIONS:
352 *
353 *NOTE:
354 *
355 * @param pMac - Pointer to Global MAC structure
356 * @param pStaDs - Pointer to DPH node
357 * @param pPeer - Pointer to IBSS peer node
358 *
359 * @return None
360 */
361
362static void
363ibss_sta_info_update(
364 tpAniSirGlobal pMac,
365 tpDphHashNode pStaDs,
366 tLimIbssPeerNode *pPeer,
367 tpPESession psessionEntry)
368{
369 pStaDs->staType = STA_ENTRY_PEER;
370 ibss_sta_caps_update(pMac, pPeer,psessionEntry);
371 ibss_sta_rates_update(pMac, pStaDs, pPeer,psessionEntry);
372} /*** end ibss_sta_info_update() ***/
373
374static void
375ibss_coalesce_free(
376 tpAniSirGlobal pMac)
377{
378 if (pMac->lim.ibssInfo.pHdr != NULL)
379 palFreeMemory(pMac->hHdd, pMac->lim.ibssInfo.pHdr);
380 if (pMac->lim.ibssInfo.pBeacon != NULL)
381 palFreeMemory(pMac->hHdd, pMac->lim.ibssInfo.pBeacon);
382
383 pMac->lim.ibssInfo.pHdr = NULL;
384 pMac->lim.ibssInfo.pBeacon = NULL;
385}
386
387/*
388 * save the beacon params for use when adding the bss
389 */
390static void
391ibss_coalesce_save(
392 tpAniSirGlobal pMac,
393 tpSirMacMgmtHdr pHdr,
394 tpSchBeaconStruct pBeacon)
395{
396 eHalStatus status;
397
398 // get rid of any saved info
399 ibss_coalesce_free(pMac);
400
401 status = palAllocateMemory(pMac->hHdd, (void **) &pMac->lim.ibssInfo.pHdr,
402 sizeof(*pHdr));
403 if (status != eHAL_STATUS_SUCCESS)
404 {
405 PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pHdr\n"));)
406 return;
407 }
408 status = palAllocateMemory(pMac->hHdd, (void **) &pMac->lim.ibssInfo.pBeacon,
409 sizeof(*pBeacon));
410 if (status != eHAL_STATUS_SUCCESS)
411 {
412 PELOGE(limLog(pMac, LOGE, FL("ibbs-save: Failed malloc pBeacon\n"));)
413 ibss_coalesce_free(pMac);
414 return;
415 }
416
417 palCopyMemory(pMac->hHdd, pMac->lim.ibssInfo.pHdr, pHdr, sizeof(*pHdr));
418 palCopyMemory(pMac->hHdd, pMac->lim.ibssInfo.pBeacon, pBeacon, sizeof(*pBeacon));
419}
420
421/*
422 * tries to add a new entry to dph hash node
423 * if necessary, an existing entry is eliminated
424 */
425static tSirRetStatus
426ibss_dph_entry_add(
427 tpAniSirGlobal pMac,
428 tSirMacAddr peerAddr,
429 tpDphHashNode *ppSta,
430 tpPESession psessionEntry)
431{
432 tANI_U16 aid;
433 tpDphHashNode pStaDs;
434
435 *ppSta = NULL;
436
437 pStaDs = dphLookupHashEntry(pMac, peerAddr, &aid, &psessionEntry->dph.dphHashTable);
438 if (pStaDs != NULL)
439 {
440 /* Trying to add context for already existing STA in IBSS */
441 PELOGE(limLog(pMac, LOGE, FL("STA exists already "));)
442 limPrintMacAddr(pMac, peerAddr, LOGE);
443 return eSIR_FAILURE;
444 }
445
446 /**
447 * Assign an AID, delete context existing with that
448 * AID and then add an entry to hash table maintained
449 * by DPH module.
450 */
451 aid = limAssignAID(pMac);
452
453 pStaDs = dphGetHashEntry(pMac, aid, &psessionEntry->dph.dphHashTable);
454 if (pStaDs)
455 {
456 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry);
457 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid,psessionEntry);
458 }
459
460 pStaDs = dphAddHashEntry(pMac, peerAddr, aid, &psessionEntry->dph.dphHashTable);
461 if (pStaDs == NULL)
462 {
463 // Could not add hash table entry
464 PELOGE(limLog(pMac, LOGE, FL("could not add hash entry at DPH for aid=%d MACaddr:\n"), aid);)
465 limPrintMacAddr(pMac, peerAddr, LOGE);
466 return eSIR_FAILURE;
467 }
468
469 *ppSta = pStaDs;
470 return eSIR_SUCCESS;
471}
472
473// send a status change notification
474static void
475ibss_status_chg_notify(
476 tpAniSirGlobal pMac,
477 tSirMacAddr peerAddr,
478 tANI_U16 staIndex,
479 tANI_U8 ucastSig,
480 tANI_U8 bcastSig,
481 tANI_U16 status,
482 tANI_U8 sessionId)
483{
484
485 tLimIbssPeerNode *peerNode;
486 tANI_U8 *beacon = NULL;
487 tANI_U16 bcnLen = 0;
488
489
490 peerNode = ibss_peer_find(pMac,peerAddr);
491 if(peerNode != NULL)
492 {
493 if(peerNode->beacon == NULL) peerNode->beaconLen = 0;
494 beacon = peerNode->beacon;
495 bcnLen = peerNode->beaconLen;
496 peerNode->beacon = NULL;
497 peerNode->beaconLen = 0;
498 }
499
500 limSendSmeIBSSPeerInd(pMac,peerAddr, staIndex, ucastSig, bcastSig,
501 beacon, bcnLen, status, sessionId);
502
503 if(beacon != NULL)
504 {
505 palFreeMemory(pMac->hHdd, beacon);
506 }
507}
508
509
510static void
511ibss_bss_add(
512 tpAniSirGlobal pMac,
513 tpPESession psessionEntry)
514{
515 tLimMlmStartReq mlmStartReq;
516 tANI_U32 cfg;
517 tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
518 tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
519 tANI_U8 numExtRates = 0;
520
521 if ((pHdr == NULL) || (pBeacon == NULL))
522 {
523 PELOGE(limLog(pMac, LOGE, FL("Unable to add BSS (no cached BSS info)\n"));)
524 return;
525 }
526
527 palCopyMemory( pMac->hHdd, psessionEntry->bssId, pHdr->bssId,
528 sizeof(tSirMacAddr));
529
530 #if 0
531 if (cfgSetStr(pMac, WNI_CFG_BSSID, (tANI_U8 *) pHdr->bssId, sizeof(tSirMacAddr))
532 != eSIR_SUCCESS)
533 limLog(pMac, LOGP, FL("could not update BSSID at CFG\n"));
534 #endif //TO SUPPORT BT-AMP
535
536 sirCopyMacAddr(pHdr->bssId,psessionEntry->bssId);
537 /* We need not use global Mac address since per seesion BSSID is available */
538 //limSetBssid(pMac, pHdr->bssId);
539
540#if 0
541 if (wlan_cfgGetInt(pMac, WNI_CFG_BEACON_INTERVAL, &cfg) != eSIR_SUCCESS)
542 limLog(pMac, LOGP, FL("Can't read beacon interval\n"));
543#endif //TO SUPPORT BT-AMP
544 /* Copy beacon interval from sessionTable */
545 cfg = psessionEntry->beaconParams.beaconInterval;
546 if (cfg != pBeacon->beaconInterval)
547 #if 0
548 if (cfgSetInt(pMac, WNI_CFG_BEACON_INTERVAL, pBeacon->beaconInterval)
549 != eSIR_SUCCESS)
550 limLog(pMac, LOGP, FL("Can't update beacon interval\n"));
551 #endif//TO SUPPORT BT-AMP
552 psessionEntry->beaconParams.beaconInterval = pBeacon->beaconInterval;
553
554 /* This function ibss_bss_add (and hence the below code) is only called during ibss coalescing. We need to
555 * adapt to peer's capability with respect to short slot time. Changes have been made to limApplyConfiguration()
556 * so that the IBSS doesnt blindly start with short slot = 1. If IBSS start is part of coalescing then it will adapt
557 * to peer's short slot using code below.
558 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700559 /* If cfg is already set to current peer's capability then no need to set it again */
Jeff Johnsone7245742012-09-05 17:12:55 -0700560 if (psessionEntry->shortSlotTimeSupported != pBeacon->capabilityInfo.shortSlotTime)
Jeff Johnson295189b2012-06-20 16:38:30 -0700561 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700562 psessionEntry->shortSlotTimeSupported = pBeacon->capabilityInfo.shortSlotTime;
Jeff Johnson295189b2012-06-20 16:38:30 -0700563 }
564 palCopyMemory( pMac->hHdd,
565 (tANI_U8 *) &psessionEntry->pLimStartBssReq->operationalRateSet,
566 (tANI_U8 *) &pBeacon->supportedRates,
567 pBeacon->supportedRates.numRates);
568
569 #if 0
570 if (cfgSetStr(pMac, WNI_CFG_OPERATIONAL_RATE_SET,
571 (tANI_U8 *) &pMac->lim.gpLimStartBssReq->operationalRateSet.rate,
572 pMac->lim.gpLimStartBssReq->operationalRateSet.numRates)
573 != eSIR_SUCCESS)
574 limLog(pMac, LOGP, FL("could not update OperRateset at CFG\n"));
575 #endif //TO SUPPORT BT-AMP
576
577 /**
578 * WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET CFG needs to be reset, when
579 * there is no extended rate IE present in beacon. This is especially important when
580 * supportedRateSet IE contains all the extended rates as well and STA decides to coalesce.
581 * In this IBSS coalescing scenario LIM will tear down the BSS and Add a new one. So LIM needs to
582 * reset this CFG, just in case CSR originally had set this CFG when IBSS was started from the local profile.
583 * If IBSS was started by CSR from the BssDescription, then it would reset this CFG before StartBss is issued.
584 * The idea is that the count of OpRateSet and ExtendedOpRateSet rates should not be more than 12.
585 */
586
587 if(pBeacon->extendedRatesPresent)
588 numExtRates = pBeacon->extendedRates.numRates;
589 if (cfgSetStr(pMac, WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
590 (tANI_U8 *) &pBeacon->extendedRates.rate, numExtRates) != eSIR_SUCCESS)
591 {
592 limLog(pMac, LOGP, FL("could not update ExtendedOperRateset at CFG\n"));
593 return;
594 }
595
596
597 /*
598 * Each IBSS node will advertise its own HT Capabilities instead of adapting to the Peer's capabilities
599 * If we don't do this then IBSS may not go back to full capabilities when the STA with lower capabilities
600 * leaves the IBSS. e.g. when non-CB STA joins an IBSS and then leaves, the IBSS will be stuck at non-CB mode
601 * even though all the nodes are capable of doing CB.
602 * so it is decided to leave the self HT capabilties intact. This may change if some issues are found in interop.
603 */
604 palZeroMemory(pMac->hHdd, (void *) &mlmStartReq, sizeof(mlmStartReq));
605
606 palCopyMemory(pMac->hHdd, mlmStartReq.bssId, pHdr->bssId, sizeof(tSirMacAddr));
607 mlmStartReq.rateSet.numRates = psessionEntry->pLimStartBssReq->operationalRateSet.numRates;
608 palCopyMemory(pMac->hHdd, &mlmStartReq.rateSet.rate[0],
609 &psessionEntry->pLimStartBssReq->operationalRateSet.rate[0],
610 mlmStartReq.rateSet.numRates);
611 mlmStartReq.bssType = eSIR_IBSS_MODE;
612 mlmStartReq.beaconPeriod = pBeacon->beaconInterval;
613 mlmStartReq.nwType = psessionEntry->pLimStartBssReq->nwType; //psessionEntry->nwType is also OK????
Jeff Johnsone7245742012-09-05 17:12:55 -0700614 mlmStartReq.htCapable = psessionEntry->htCapability;
Jeff Johnson295189b2012-06-20 16:38:30 -0700615 mlmStartReq.htOperMode = pMac->lim.gHTOperMode;
616 mlmStartReq.dualCTSProtection = pMac->lim.gHTDualCTSProtection;
Jeff Johnsone7245742012-09-05 17:12:55 -0700617 mlmStartReq.txChannelWidthSet = psessionEntry->htRecommendedTxWidthSet;
Jeff Johnson295189b2012-06-20 16:38:30 -0700618
619 #if 0
620 if (wlan_cfgGetInt(pMac, WNI_CFG_CURRENT_CHANNEL, &cfg) != eSIR_SUCCESS)
621 limLog(pMac, LOGP, FL("CurrentChannel CFG get fialed!\n"));
622 #endif
623
624 //mlmStartReq.channelNumber = (tSirMacChanNum) cfg;
625
626 /* reading the channel num from session Table */
627 mlmStartReq.channelNumber = psessionEntry->currentOperChannel;
628
629 mlmStartReq.cbMode = psessionEntry->pLimStartBssReq->cbMode;
630
631 // Copy the SSID for RxP filtering based on SSID.
632 palCopyMemory( pMac->hHdd, (tANI_U8 *) &mlmStartReq.ssId,
633 (tANI_U8 *) &psessionEntry->pLimStartBssReq->ssId,
634 psessionEntry->pLimStartBssReq->ssId.length + 1);
635
636 PELOG1(limLog(pMac, LOG1, FL("invoking ADD_BSS as part of coalescing!\n"));)
637 if (limMlmAddBss(pMac, &mlmStartReq,psessionEntry) != eSIR_SME_SUCCESS)
638 {
639 PELOGE(limLog(pMac, LOGE, FL("AddBss failure\n"));)
640 return;
641 }
642
643 // Update fields in Beacon
644 if (schSetFixedBeaconFields(pMac,psessionEntry) != eSIR_SUCCESS)
645 {
646 PELOGE(limLog(pMac, LOGE, FL("*** Unable to set fixed Beacon fields ***\n"));)
647 return;
648 }
649
650}
651
652
653
654/* delete the current BSS */
655static void
656ibss_bss_delete(
657 tpAniSirGlobal pMac,
658 tpPESession psessionEntry)
659{
660 tSirRetStatus status;
661 PELOGW(limLog(pMac, LOGW, FL("Initiating IBSS Delete BSS\n"));)
662 if (psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE)
663 {
664 limLog(pMac, LOGW, FL("Incorrect LIM MLM state for delBss (%d)\n"),
665 psessionEntry->limMlmState);
666 return;
667 }
668 status = limDelBss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
669 if (status != eSIR_SUCCESS)
670 PELOGE(limLog(pMac, LOGE, FL("delBss failed for bss %d\n"), psessionEntry->bssIdx);)
671}
672
673/**
674 * limIbssInit
675 *
676 *FUNCTION:
677 * This function is called while starting an IBSS
678 * to initialize list used to maintain IBSS peers.
679 *
680 *LOGIC:
681 *
682 *ASSUMPTIONS:
683 *
684 *NOTE:
685 *
686 * @param pMac - Pointer to Global MAC structure
687 * @return None
688 */
689
690void
691limIbssInit(
692 tpAniSirGlobal pMac)
693{
694 //pMac->lim.gLimIbssActive = 0;
695 pMac->lim.gLimIbssCoalescingHappened = 0;
696 pMac->lim.gLimIbssPeerList = NULL;
697 pMac->lim.gLimNumIbssPeers = 0;
698
699 // ibss info - params for which ibss to join while coalescing
700 palZeroMemory(pMac->hHdd, &pMac->lim.ibssInfo, sizeof(tAniSirLimIbss));
701} /*** end limIbssInit() ***/
702
703/**
704 * limIbssDeleteAllPeers
705 *
706 *FUNCTION:
707 * This function is called to delete all peers.
708 *
709 *LOGIC:
710 *
711 *ASSUMPTIONS:
712 *
713 *NOTE:
714 *
715 * @param pMac - Pointer to Global MAC structure
716 * @return None
717 */
718
719void limIbssDeleteAllPeers( tpAniSirGlobal pMac ,tpPESession psessionEntry)
720{
721 tLimIbssPeerNode *pCurrNode, *pTempNode;
722 tpDphHashNode pStaDs;
723 tANI_U16 aid;
724
725 pCurrNode = pTempNode = pMac->lim.gLimIbssPeerList;
726
727 while (pCurrNode != NULL)
728 {
729 if (!pMac->lim.gLimNumIbssPeers)
730 {
731 limLog(pMac, LOGP,
732 FL("Number of peers in the list is zero and node present"));
733 return;
734 }
735 /* Delete the dph entry for the station
736 * Since it is called to remove all peers, just delete from dph,
737 * no need to do any beacon related params i.e., dont call limDeleteDphHashEntry
738 */
739 pStaDs = dphLookupHashEntry(pMac, pCurrNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
740 if( pStaDs )
741 {
742
743 ibss_status_chg_notify( pMac, pCurrNode->peerMacAddr, pStaDs->staIndex,
744 pStaDs->ucUcastSig, pStaDs->ucBcastSig,
745 eWNI_SME_IBSS_PEER_DEPARTED_IND, psessionEntry->smeSessionId );
746 dphDeleteHashEntry(pMac, pStaDs->staAddr, aid, &psessionEntry->dph.dphHashTable);
747 }
748
749 pTempNode = pCurrNode->next;
750
751 /* TODO :Sessionize this code */
752 /* Fix CR 227642: PeerList should point to the next node since the current node is being
753 * freed in the next line. In ibss_peerfind in ibss_status_chg_notify above, we use this
754 * peer list to find the next peer. So this list needs to be updated with the no of peers left
755 * after each iteration in this while loop since one by one peers are deleted (freed) in this
756 * loop causing the lim.gLimIbssPeerList to point to some freed memory.
757 */
758 pMac->lim.gLimIbssPeerList = pTempNode;
759
760 if(pCurrNode->beacon)
761 {
762 palFreeMemory(pMac->hHdd, pCurrNode->beacon);
763 }
764 palFreeMemory( pMac->hHdd, (tANI_U8 *) pCurrNode);
765 if (pMac->lim.gLimNumIbssPeers > 0) // be paranoid
766 pMac->lim.gLimNumIbssPeers--;
767 pCurrNode = pTempNode;
768 }
769
770 if (pMac->lim.gLimNumIbssPeers)
771 limLog(pMac, LOGP, FL("Number of peers[%d] in the list is non-zero"),
772 pMac->lim.gLimNumIbssPeers);
773
774 pMac->lim.gLimNumIbssPeers = 0;
775 pMac->lim.gLimIbssPeerList = NULL;
776
777}
778/**
779 * limIbssDelete
780 *
781 *FUNCTION:
782 * This function is called while tearing down an IBSS.
783 *
784 *LOGIC:
785 *
786 *ASSUMPTIONS:
787 *
788 *NOTE:
789 *
790 * @param pMac - Pointer to Global MAC structure
791 * @return None
792 */
793
794void
795limIbssDelete(
796 tpAniSirGlobal pMac,tpPESession psessionEntry)
797{
798 limIbssDeleteAllPeers(pMac,psessionEntry);
799
800 ibss_coalesce_free(pMac);
801} /*** end limIbssDelete() ***/
802
803/** Commenting this Code as from no where it is being invoked */
804#if 0
805/**
806 * limIbssPeerDelete
807 *
808 *FUNCTION:
809 * This may be called on a STA in IBSS to delete a peer
810 * from the list.
811 *
812 *LOGIC:
813 *
814 *ASSUMPTIONS:
815 *
816 *NOTE:
817 *
818 * @param pMac - Pointer to Global MAC structure
819 * @param peerMacAddr - MAC address of the peer STA that
820 * need to be deleted from peer list.
821 *
822 * @return None
823 */
824
825void
826limIbssPeerDelete(tpAniSirGlobal pMac, tSirMacAddr macAddr)
827{
828 tLimIbssPeerNode *pPrevNode, *pTempNode;
829
830 pTempNode = pPrevNode = pMac->lim.gLimIbssPeerList;
831
832 if (pTempNode == NULL)
833 return;
834
835 while (pTempNode != NULL)
836 {
837 if (palEqualMemory( pMac->hHdd,(tANI_U8 *) macAddr,
838 (tANI_U8 *) &pTempNode->peerMacAddr,
839 sizeof(tSirMacAddr)) )
840 {
841 // Found node to be deleted
842 if (pMac->lim.gLimIbssPeerList == pTempNode) /** First Node to be deleted*/
843 pMac->lim.gLimIbssPeerList = pTempNode->next;
844 else
845 pPrevNode->next = pTempNode->next;
846
847 if(pTempNode->beacon)
848 {
849 palFreeMemory(pMac->hHdd, pTempNode->beacon);
850 pTempNode->beacon = NULL;
851 }
852 palFreeMemory( pMac->hHdd, (tANI_U8 *) pTempNode);
853 pMac->lim.gLimNumIbssPeers--;
854 return;
855 }
856
857 pPrevNode = pTempNode;
858 pTempNode = pTempNode->next;
859 }
860
861 // Should not be here
862 PELOGE(limLog(pMac, LOGE, FL("peer not found in the list, addr= "));)
863 limPrintMacAddr(pMac, macAddr, LOGE);
864} /*** end limIbssPeerDelete() ***/
865
866#endif
867
868
869/** -------------------------------------------------------------
870\fn limIbssSetProtection
871\brief Decides all the protection related information.
872\
873\param tpAniSirGlobal pMac
874\param tSirMacAddr peerMacAddr
875\param tpUpdateBeaconParams pBeaconParams
876\return None
877 -------------------------------------------------------------*/
878static void
879limIbssSetProtection(tpAniSirGlobal pMac, tANI_U8 enable, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
880{
881
882 if(!pMac->lim.cfgProtection.fromllb)
883 {
884 PELOG1(limLog(pMac, LOG1, FL("protection from 11b is disabled\n"));)
885 return;
886 }
887
888 if (enable)
889 {
890 psessionEntry->gLim11bParams.protectionEnabled = true;
891 if(false == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/)
892 {
893 PELOGE(limLog(pMac, LOGE, FL("=> IBSS: Enable Protection \n"));)
894 pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = true;
895 pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
896 }
897 }
898 else if (true == psessionEntry->beaconParams.llbCoexist/*pMac->lim.llbCoexist*/)
899 {
900 psessionEntry->gLim11bParams.protectionEnabled = false;
901 PELOGE(limLog(pMac, LOGE, FL("===> IBSS: Disable protection \n"));)
902 pBeaconParams->llbCoexist = psessionEntry->beaconParams.llbCoexist = false;
903 pBeaconParams->paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED;
904 }
905 return;
906}
907
908
909/** -------------------------------------------------------------
910\fn limIbssUpdateProtectionParams
911\brief Decides all the protection related information.
912\
913\param tpAniSirGlobal pMac
914\param tSirMacAddr peerMacAddr
915\param tpUpdateBeaconParams pBeaconParams
916\return None
917 -------------------------------------------------------------*/
918static void
919limIbssUpdateProtectionParams(tpAniSirGlobal pMac,
920 tSirMacAddr peerMacAddr, tLimProtStaCacheType protStaCacheType,
921 tpPESession psessionEntry)
922{
923 tANI_U32 i;
924
925 PELOG1(limLog(pMac,LOG1, FL("A STA is associated:"));
926 limLog(pMac,LOG1, FL("Addr : "));
927 limPrintMacAddr(pMac, peerMacAddr, LOG1);)
928
929 for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
930 {
931 if (pMac->lim.protStaCache[i].active)
932 {
933 PELOG1(limLog(pMac, LOG1, FL("Addr: "));)
934 PELOG1(limPrintMacAddr(pMac, pMac->lim.protStaCache[i].addr, LOG1);)
935
936 if (palEqualMemory( pMac->hHdd,
937 pMac->lim.protStaCache[i].addr,
938 peerMacAddr, sizeof(tSirMacAddr)))
939 {
940 PELOG1(limLog(pMac, LOG1, FL("matching cache entry at %d already active.\n"), i);)
941 return;
942 }
943 }
944 }
945
946 for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
947 {
948 if (!pMac->lim.protStaCache[i].active)
949 break;
950 }
951
952 if (i >= LIM_PROT_STA_CACHE_SIZE)
953 {
954 PELOGE(limLog(pMac, LOGE, FL("No space in ProtStaCache\n"));)
955 return;
956 }
957
958 palCopyMemory( pMac->hHdd, pMac->lim.protStaCache[i].addr,
959 peerMacAddr,
960 sizeof(tSirMacAddr));
961
962 pMac->lim.protStaCache[i].protStaCacheType = protStaCacheType;
963 pMac->lim.protStaCache[i].active = true;
964 if(eLIM_PROT_STA_CACHE_TYPE_llB == protStaCacheType)
965 {
966 psessionEntry->gLim11bParams.numSta++;
967 }
968 else if(eLIM_PROT_STA_CACHE_TYPE_llG == protStaCacheType)
969 {
970 psessionEntry->gLim11gParams.numSta++;
971 }
972}
973
974
975/** -------------------------------------------------------------
976\fn limIbssDecideProtection
977\brief Decides all the protection related information.
978\
979\param tpAniSirGlobal pMac
980\param tSirMacAddr peerMacAddr
981\param tpUpdateBeaconParams pBeaconParams
982\return None
983 -------------------------------------------------------------*/
984static void
985limIbssDecideProtection(tpAniSirGlobal pMac, tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
986{
987 tSirRFBand rfBand = SIR_BAND_UNKNOWN;
988 tANI_U32 phyMode;
989 tLimProtStaCacheType protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_INVALID;
990
991 pBeaconParams->paramChangeBitmap = 0;
992
993 if(NULL == pStaDs)
994 {
995 PELOGE(limLog(pMac, LOGE, FL("pStaDs is NULL\n"));)
996 return;
997 }
998
999 limGetRfBand(pMac, &rfBand, psessionEntry);
1000 if(SIR_BAND_2_4_GHZ== rfBand)
1001 {
1002 limGetPhyMode(pMac, &phyMode, psessionEntry);
1003
1004 //We are 11G or 11n. Check if we need protection from 11b Stations.
Jeff Johnsone7245742012-09-05 17:12:55 -07001005 if ((phyMode == WNI_CFG_PHY_MODE_11G) || (psessionEntry->htCapability))
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 {
1007 /* As we found in the past, it is possible that a 11n STA sends
1008 * Beacon with HT IE but not ERP IE. So the absense of ERP IE
1009 * in the Beacon is not enough to conclude that STA is 11b.
1010 */
1011 if ((pStaDs->erpEnabled == eHAL_CLEAR) &&
1012 (!pStaDs->mlmStaContext.htCapability))
1013 {
1014 protStaCacheType = eLIM_PROT_STA_CACHE_TYPE_llB;
1015 PELOGE(limLog(pMac, LOGE, FL("Enable protection from 11B\n"));)
1016 limIbssSetProtection(pMac, true, pBeaconParams,psessionEntry);
1017 }
1018 }
1019 }
1020 limIbssUpdateProtectionParams(pMac, pStaDs->staAddr, protStaCacheType, psessionEntry);
1021 return;
1022}
1023
1024
1025/**
1026 * limIbssStaAdd()
1027 *
1028 *FUNCTION:
1029 * This function is called to add an STA context in IBSS role
1030 * whenever a data frame is received from/for a STA that failed
1031 * hash lookup at DPH.
1032 *
1033 *LOGIC:
1034 *
1035 *ASSUMPTIONS:
1036 * NA
1037 *
1038 *NOTE:
1039 * NA
1040 *
1041 * @param pMac Pointer to Global MAC structure
1042 * @param peerAdddr MAC address of the peer being added
1043 * @return retCode Indicates success or failure return code
1044 * @return
1045 */
1046
1047tSirRetStatus
1048limIbssStaAdd(
1049 tpAniSirGlobal pMac,
1050 void *pBody,
1051 tpPESession psessionEntry)
1052{
1053 tSirRetStatus retCode = eSIR_SUCCESS;
1054 tpDphHashNode pStaDs;
1055 tLimIbssPeerNode *pPeerNode;
1056 tLimMlmStates prevState;
1057 tSirMacAddr *pPeerAddr = (tSirMacAddr *) pBody;
1058 tUpdateBeaconParams beaconParams;
1059
1060 palZeroMemory( pMac->hHdd, (tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams));
1061
1062 if (pBody == 0)
1063 {
1064 PELOGE(limLog(pMac, LOGE, FL("Invalid IBSS AddSta\n"));)
1065 return eSIR_FAILURE;
1066 }
1067
1068 PELOGE(limLog(pMac, LOGE, FL("Rx Add-Ibss-Sta for MAC:\n"));)
1069 limPrintMacAddr(pMac, *pPeerAddr, LOGE);
1070
1071 pPeerNode = ibss_peer_find(pMac, *pPeerAddr);
1072 if(NULL != pPeerNode)
1073 {
1074 retCode = ibss_dph_entry_add(pMac, *pPeerAddr, &pStaDs,psessionEntry);
1075 if (eSIR_SUCCESS == retCode)
1076 {
1077 prevState = pStaDs->mlmStaContext.mlmState;
1078 pStaDs->erpEnabled = pPeerNode->erpIePresent;
1079
1080 ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry);
1081 PELOGW(limLog(pMac, LOGW, FL("initiating ADD STA for the IBSS peer.\n"));)
1082 retCode = limAddSta(pMac, pStaDs,psessionEntry);
1083 if(retCode != eSIR_SUCCESS)
1084 {
1085 PELOGE(limLog(pMac, LOGE, FL("ibss-sta-add failed (reason %x)\n"), retCode);)
1086 limPrintMacAddr(pMac, *pPeerAddr, LOGE);
1087 if(NULL != pStaDs)
1088 {
1089 pStaDs->mlmStaContext.mlmState = prevState;
1090 dphDeleteHashEntry(pMac, pStaDs->staAddr, pStaDs->assocId, &psessionEntry->dph.dphHashTable);
1091 }
1092 }
1093 else
1094 {
1095 if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
1096 limIbssDecideProtection(pMac, pStaDs, &beaconParams , psessionEntry);
1097
1098 if(beaconParams.paramChangeBitmap)
1099 {
1100 PELOGE(limLog(pMac, LOGE, FL("---> Update Beacon Params \n"));)
1101 schSetFixedBeaconFields(pMac, psessionEntry);
1102 limSendBeaconParams(pMac, &beaconParams, psessionEntry );
1103 }
1104 }
1105 }
1106 else
1107 {
1108 PELOGE(limLog(pMac, LOGE, FL("hashTblAdd failed (reason %x)\n"), retCode);)
1109 limPrintMacAddr(pMac, *pPeerAddr, LOGE);
1110 }
1111 }
1112 else
1113 {
1114 retCode = eSIR_FAILURE;
1115 }
1116
1117 return retCode;
1118}
1119
1120/* handle the response from HAL for an ADD STA request */
1121tSirRetStatus
1122limIbssAddStaRsp(
1123 tpAniSirGlobal pMac,
1124 void *msg,tpPESession psessionEntry)
1125{
1126 tpDphHashNode pStaDs;
1127 tANI_U16 aid;
1128 tpAddStaParams pAddStaParams = (tpAddStaParams) msg;
1129
1130 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1131 if (pAddStaParams == NULL)
1132 {
1133 PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP with no body!\n"));)
1134 return eSIR_FAILURE;
1135 }
1136
1137 pStaDs = dphLookupHashEntry(pMac, pAddStaParams->staMac, &aid, &psessionEntry->dph.dphHashTable);
1138 if (pStaDs == NULL)
1139 {
1140 PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP for unknown MAC addr "));)
1141 limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE);
1142 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
1143 return eSIR_FAILURE;
1144 }
1145
1146 if (pAddStaParams->status != eHAL_STATUS_SUCCESS)
1147 {
1148 PELOGE(limLog(pMac, LOGE, FL("IBSS: ADD_STA_RSP error (%x) "), pAddStaParams->status);)
1149 limPrintMacAddr(pMac, pAddStaParams->staMac, LOGE);
1150 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
1151 return eSIR_FAILURE;
1152 }
1153
1154 pStaDs->bssId = pAddStaParams->bssIdx;
1155 pStaDs->staIndex = pAddStaParams->staIdx;
1156 pStaDs->ucUcastSig = pAddStaParams->ucUcastSig;
1157 pStaDs->ucBcastSig = pAddStaParams->ucBcastSig;
1158 pStaDs->valid = 1;
1159 pStaDs->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE;
1160
1161 PELOGW(limLog(pMac, LOGW, FL("IBSS: sending IBSS_NEW_PEER msg to SME!\n"));)
1162
1163 ibss_status_chg_notify(pMac, pAddStaParams->staMac, pStaDs->staIndex,
1164 pStaDs->ucUcastSig, pStaDs->ucBcastSig,
1165 eWNI_SME_IBSS_NEW_PEER_IND,
1166 psessionEntry->smeSessionId);
1167 palFreeMemory( pMac->hHdd, (void *) pAddStaParams );
1168
1169 return eSIR_SUCCESS;
1170}
1171
1172
1173
1174void limIbssDelBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg,tpPESession psessionEntry)
1175{
1176 tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
1177
1178 PELOGW(limLog(pMac, LOGW, FL("IBSS: DEL_BSS_RSP Rcvd during coalescing!\n"));)
1179
1180 if (pDelBss == NULL)
1181 {
1182 PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) with no body!\n"));)
1183 goto end;
1184 }
1185
1186 if (pDelBss->status != eHAL_STATUS_SUCCESS)
1187 {
1188 limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP(coalesce) error (%x) Bss %d "),
1189 pDelBss->status, pDelBss->bssIdx);
1190 goto end;
1191 }
1192 //Delete peer entries.
1193 limIbssDeleteAllPeers(pMac,psessionEntry);
1194
1195 /* add the new bss */
1196 ibss_bss_add(pMac,psessionEntry);
1197
1198 end:
1199 if(pDelBss != NULL)
1200 palFreeMemory( pMac->hHdd, (void *) pDelBss );
1201}
1202
1203
1204
1205void limIbssAddBssRspWhenCoalescing(tpAniSirGlobal pMac, void *msg, tpPESession pSessionEntry)
1206{
1207 tANI_U8 infoLen;
1208 tSirSmeNewBssInfo newBssInfo;
1209
1210 tpAddBssParams pAddBss = (tpAddBssParams) msg;
1211
1212 tpSirMacMgmtHdr pHdr = (tpSirMacMgmtHdr) pMac->lim.ibssInfo.pHdr;
1213 tpSchBeaconStruct pBeacon = (tpSchBeaconStruct) pMac->lim.ibssInfo.pBeacon;
1214
1215 if ((pHdr == NULL) || (pBeacon == NULL))
1216 {
1217 PELOGE(limLog(pMac, LOGE, FL("Unable to handle AddBssRspWhenCoalescing (no cached BSS info)\n"));)
1218 goto end;
1219 }
1220
1221 // Inform Host of IBSS coalescing
1222 infoLen = sizeof(tSirMacAddr) + sizeof(tSirMacChanNum) +
1223 sizeof(tANI_U8) + pBeacon->ssId.length + 1;
1224
1225 palZeroMemory(pMac->hHdd, (void *) &newBssInfo, sizeof(newBssInfo));
1226 palCopyMemory( pMac->hHdd, newBssInfo.bssId, pHdr->bssId, sizeof(tSirMacAddr));
1227 newBssInfo.channelNumber = (tSirMacChanNum) pAddBss->currentOperChannel;
1228 palCopyMemory( pMac->hHdd, (tANI_U8 *) &newBssInfo.ssId,
1229 (tANI_U8 *) &pBeacon->ssId, pBeacon->ssId.length + 1);
1230
1231 PELOGW(limLog(pMac, LOGW, FL("Sending JOINED_NEW_BSS notification to SME.\n"));)
1232
1233 limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_JOINED_NEW_BSS,
1234 (tANI_U32 *) &newBssInfo,
1235 infoLen,pSessionEntry->smeSessionId);
1236#ifdef WLAN_SOFTAP_FEATURE
1237 {
1238 //Configure beacon and send beacons to HAL
1239 limSendBeaconInd(pMac, pSessionEntry);
1240 }
1241#endif
1242
1243
1244 end:
1245 ibss_coalesce_free(pMac);
1246}
1247
1248
1249
1250void
1251limIbssDelBssRsp(
1252 tpAniSirGlobal pMac,
1253 void *msg,tpPESession psessionEntry)
1254{
1255 tSirResultCodes rc = eSIR_SME_SUCCESS;
1256 tpDeleteBssParams pDelBss = (tpDeleteBssParams) msg;
1257 tSirMacAddr nullBssid = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1258
1259
1260 SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
1261 if (pDelBss == NULL)
1262 {
1263 PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP with no body!\n"));)
1264 rc = eSIR_SME_REFUSED;
1265 goto end;
1266 }
1267
1268 if((psessionEntry = peFindSessionBySessionId(pMac,pDelBss->sessionId))==NULL)
1269 {
1270 limLog(pMac, LOGP,FL("Session Does not exist for given sessionID\n"));
1271 goto end;
1272 }
1273
1274
1275 /*
1276 * If delBss was issued as part of IBSS Coalescing, gLimIbssCoalescingHappened flag will be true.
1277 * BSS has to be added again in this scenario, so this case needs to be handled separately.
1278 * If delBss was issued as a result of trigger from SME_STOP_BSS Request, then limSme state changes to
1279 * 'IDLE' and gLimIbssCoalescingHappened flag will be false. In this case STOP BSS RSP has to be sent to SME.
1280 */
1281 if(true == pMac->lim.gLimIbssCoalescingHappened)
1282 {
1283
1284 limIbssDelBssRspWhenCoalescing(pMac,msg,psessionEntry);
1285 return;
1286 }
1287
1288
1289
1290 if (pDelBss->status != eHAL_STATUS_SUCCESS)
1291 {
1292 PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP error (%x) Bss %d "),
1293 pDelBss->status, pDelBss->bssIdx);)
1294 rc = eSIR_SME_STOP_BSS_FAILURE;
1295 goto end;
1296 }
1297
1298
1299
1300 if(limSetLinkState(pMac, eSIR_LINK_IDLE_STATE, nullBssid,
1301 psessionEntry->selfMacAddr, NULL, NULL) != eSIR_SUCCESS)
1302 {
1303 PELOGE(limLog(pMac, LOGE, FL("IBSS: DEL_BSS_RSP setLinkState failed\n"));)
1304 rc = eSIR_SME_REFUSED;
1305 goto end;
1306 }
1307
1308 dphHashTableClassInit(pMac, &psessionEntry->dph.dphHashTable);
1309 limDeletePreAuthList(pMac);
1310
1311 limIbssDelete(pMac,psessionEntry);
1312 psessionEntry->limMlmState = eLIM_MLM_IDLE_STATE;
1313
Jeff Johnsone7245742012-09-05 17:12:55 -07001314 MTRACE(macTrace(pMac, TRACE_CODE_MLM_STATE, psessionEntry->peSessionId, psessionEntry->limMlmState));
Jeff Johnson295189b2012-06-20 16:38:30 -07001315
1316 psessionEntry->limSystemRole = eLIM_STA_ROLE;
1317
1318 /* Change the short slot operating mode to Default (which is 1 for now) so that when IBSS starts next time with Libra
1319 * as originator, it picks up the default. This enables us to remove hard coding of short slot = 1 from limApplyConfiguration
1320 */
Jeff Johnsone7245742012-09-05 17:12:55 -07001321 psessionEntry->shortSlotTimeSupported = WNI_CFG_SHORT_SLOT_TIME_STADEF;
Jeff Johnson295189b2012-06-20 16:38:30 -07001322
1323 end:
1324 if(pDelBss != NULL)
1325 palFreeMemory( pMac->hHdd, (void *) pDelBss );
1326 /* Delete PE session once BSS is deleted */
1327 if (NULL != psessionEntry) {
1328 limSendSmeRsp(pMac, eWNI_SME_STOP_BSS_RSP, rc,psessionEntry->smeSessionId,psessionEntry->transactionId);
1329 peDeleteSession(pMac, psessionEntry);
1330 psessionEntry = NULL;
1331 }
1332}
1333
1334/**
1335 * limIbssCoalesce()
1336 *
1337 *FUNCTION:
1338 * This function is called upon receiving Beacon/Probe Response
1339 * while operating in IBSS mode.
1340 *
1341 *LOGIC:
1342 *
1343 *ASSUMPTIONS:
1344 *
1345 *NOTE:
1346 *
1347 * @param pMac - Pointer to Global MAC structure
1348 * @param pBeacon - Parsed Beacon Frame structure
1349 * @param pBD - Pointer to received BD
1350 *
1351 * @return Status whether to process or ignore received Beacon Frame
1352 */
1353
1354tSirRetStatus
1355limIbssCoalesce(
1356 tpAniSirGlobal pMac,
1357 tpSirMacMgmtHdr pHdr,
1358 tpSchBeaconStruct pBeacon,
1359 tANI_U8 *pIEs,
1360 tANI_U32 ieLen,
1361 tANI_U16 fTsfLater,
1362 tpPESession psessionEntry)
1363{
1364 tANI_U16 aid;
1365 tSirMacAddr currentBssId;
1366 tLimIbssPeerNode *pPeerNode;
1367 tpDphHashNode pStaDs;
1368 tUpdateBeaconParams beaconParams;
1369
1370 palZeroMemory( pMac->hHdd, (tANI_U8 *) &beaconParams, sizeof(tUpdateBeaconParams));
1371
1372 sirCopyMacAddr(currentBssId,psessionEntry->bssId);
1373
1374 /* Check for IBSS Coalescing only if Beacon is from different BSS */
1375 if ( !palEqualMemory( pMac->hHdd, currentBssId, pHdr->bssId, sizeof( tSirMacAddr ) ) )
1376 {
1377 if (! fTsfLater) // No Coalescing happened.
1378 return eSIR_LIM_IGNORE_BEACON;
1379 /*
1380 * IBSS Coalescing happened.
1381 * save the received beacon, and delete the current BSS. The rest of the
1382 * processing will be done in the delBss response processing
1383 */
1384 pMac->lim.gLimIbssCoalescingHappened = true;
1385 PELOGW(limLog(pMac, LOGW, FL("IBSS Coalescing happened\n"));)
1386 ibss_coalesce_save(pMac, pHdr, pBeacon);
1387 ibss_bss_delete(pMac,psessionEntry);
1388 return eSIR_SUCCESS;
1389 }
1390
1391 // STA in IBSS mode and SSID matches with ours
1392 pPeerNode = ibss_peer_find(pMac, pHdr->sa);
1393 if (pPeerNode == NULL)
1394 {
1395 /* Peer not in the list - Collect BSS description & add to the list */
1396 tANI_U32 frameLen;
1397 tSirRetStatus retCode;
1398 PELOGW(limLog(pMac, LOGW, FL("IBSS Peer node does not exist, adding it***\n"));)
1399
1400#ifndef ANI_SIR_IBSS_PEER_CACHING
1401 /** Limit the Max number of IBSS Peers allowed as the max number of STA's allowed
1402 */
1403 if (pMac->lim.gLimNumIbssPeers >= pMac->lim.maxStation)
1404 return eSIR_LIM_MAX_STA_REACHED_ERROR;
1405#endif
1406 frameLen = sizeof(tLimIbssPeerNode) + ieLen - sizeof(tANI_U32);
1407
1408 if (eHAL_STATUS_SUCCESS !=
1409 palAllocateMemory(pMac->hHdd, (void **) &pPeerNode, (tANI_U16)frameLen))
1410 {
1411 limLog(pMac, LOGP, FL("alloc fail (%d bytes) storing IBSS peer info\n"),
1412 frameLen);
1413 return eSIR_MEM_ALLOC_FAILED;
1414 }
1415
1416 pPeerNode->beacon = NULL;
1417 pPeerNode->beaconLen = 0;
1418
1419 ibss_peer_collect(pMac, pBeacon, pHdr, pPeerNode,psessionEntry);
1420 if(eHAL_STATUS_SUCCESS !=
1421 palAllocateMemory(pMac->hHdd, (void**)&pPeerNode->beacon, ieLen))
1422 {
1423 PELOGE(limLog(pMac, LOGE, FL("Unable to allocate memory to store beacon"));)
1424 }
1425 else
1426 {
1427 palCopyMemory(pMac->hHdd, pPeerNode->beacon, pIEs, ieLen);
1428 pPeerNode->beaconLen = (tANI_U16)ieLen;
1429 }
1430 ibss_peer_add(pMac, pPeerNode);
1431
1432 pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
1433 if (pStaDs != NULL)
1434 {
1435 /// DPH node already exists for the peer
1436 PELOGW(limLog(pMac, LOGW, FL("DPH Node present for just learned peer\n"));)
1437 PELOG1(limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOG1);)
1438 ibss_sta_info_update(pMac, pStaDs, pPeerNode,psessionEntry);
1439 }
1440 retCode = limIbssStaAdd(pMac, pPeerNode->peerMacAddr,psessionEntry);
1441 if (retCode != eSIR_SUCCESS)
1442 {
1443 PELOGE(limLog(pMac, LOGE, FL("lim-ibss-sta-add failed (reason %x)\n"), retCode);)
1444 limPrintMacAddr(pMac, pPeerNode->peerMacAddr, LOGE);
1445 return retCode;
1446 }
1447
1448 // Decide protection mode
1449 pStaDs = dphLookupHashEntry(pMac, pPeerNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
1450 if(pMac->lim.gLimProtectionControl != WNI_CFG_FORCE_POLICY_PROTECTION_DISABLE)
1451 limIbssDecideProtection(pMac, pStaDs, &beaconParams, psessionEntry);
1452
1453 if(beaconParams.paramChangeBitmap)
1454 {
1455 PELOGE(limLog(pMac, LOGE, FL("beaconParams.paramChangeBitmap=1 ---> Update Beacon Params \n"));)
1456 schSetFixedBeaconFields(pMac, psessionEntry);
1457 limSendBeaconParams(pMac, &beaconParams, psessionEntry );
1458 }
1459 }
1460 else
1461 ibss_sta_caps_update(pMac, pPeerNode,psessionEntry);
1462
1463 if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
1464 return eSIR_SUCCESS;
1465
1466 // Received Beacon from same IBSS we're
1467 // currently part of. Inform Roaming algorithm
1468 // if not already that IBSS is active.
1469 if (psessionEntry->limIbssActive == false)
1470 {
1471 limResetHBPktCount(psessionEntry);
1472 PELOGW(limLog(pMac, LOGW, FL("Partner joined our IBSS, Sending IBSS_ACTIVE Notification to SME\n"));)
1473 psessionEntry->limIbssActive = true;
1474 limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_ACTIVE, NULL, 0, psessionEntry->smeSessionId);
1475 limHeartBeatDeactivateAndChangeTimer(pMac, psessionEntry);
Jeff Johnsone7245742012-09-05 17:12:55 -07001476 MTRACE(macTrace(pMac, TRACE_CODE_TIMER_ACTIVATE, psessionEntry->peSessionId, eLIM_HEART_BEAT_TIMER));
Jeff Johnson295189b2012-06-20 16:38:30 -07001477 if (limActivateHearBeatTimer(pMac) != TX_SUCCESS)
1478 limLog(pMac, LOGP, FL("could not activate Heartbeat timer\n"));
1479 }
1480
1481 return eSIR_SUCCESS;
1482} /*** end limHandleIBSScoalescing() ***/
1483
1484
1485void limIbssHeartBeatHandle(tpAniSirGlobal pMac,tpPESession psessionEntry)
1486{
1487 tLimIbssPeerNode *pTempNode, *pPrevNode;
1488 tLimIbssPeerNode *pTempNextNode = NULL;
1489 tANI_U16 aid;
1490 tpDphHashNode pStaDs;
1491 tANI_U32 threshold;
1492 tANI_U16 staIndex;
1493 tANI_U8 ucUcastSig;
1494 tANI_U8 ucBcastSig;
1495
1496 /** MLM BSS is started and if PE in scanmode then MLM state will be waiting for probe resp.
1497 * If Heart beat timeout triggers during this corner case then we need to reactivate HeartBeat timer
1498 */
1499 if(psessionEntry->limMlmState != eLIM_MLM_BSS_STARTED_STATE) {
1500 /******
1501 * Note: Use this code once you have converted all
1502 * limReactivateHeartBeatTimer() calls to
1503 * limReactivateTimer() calls.
1504 *
1505 ******/
1506 //limReactivateTimer(pMac, eLIM_HEART_BEAT_TIMER, psessionEntry);
1507 limReactivateHeartBeatTimer(pMac, psessionEntry);
1508 return;
1509 }
1510 /** If LinkMonitor is Disabled */
1511 if(!pMac->sys.gSysEnableLinkMonitorMode)
1512 return;
1513
1514 pPrevNode = pTempNode = pMac->lim.gLimIbssPeerList;
1515 threshold = (pMac->lim.gLimNumIbssPeers / 4 ) + 1;
1516
1517 /** Monitor the HeartBeat with the Individual PEERS in the IBSS */
1518 while (pTempNode != NULL)
1519 {
1520 pTempNextNode = pTempNode->next;
1521 if(pTempNode->beaconHBCount) //There was a beacon for this peer during heart beat.
1522 {
1523 pTempNode->beaconHBCount = 0;
1524 pTempNode->heartbeatFailure = 0;
1525 }
1526 else //There wasnt any beacon received during heartbeat timer.
1527 {
1528 pTempNode->heartbeatFailure++;
1529 PELOGE(limLog(pMac, LOGE, FL("Heartbeat fail = %d thres = %d"), pTempNode->heartbeatFailure, pMac->lim.gLimNumIbssPeers);)
1530 if(pTempNode->heartbeatFailure >= threshold )
1531 {
1532 //Remove this entry from the list.
1533 pStaDs = dphLookupHashEntry(pMac, pTempNode->peerMacAddr, &aid, &psessionEntry->dph.dphHashTable);
1534 if (pStaDs)
1535 {
1536 staIndex = pStaDs->staIndex;
1537 ucUcastSig = pStaDs->ucUcastSig;
1538 ucBcastSig = pStaDs->ucBcastSig;
1539
1540 (void) limDelSta(pMac, pStaDs, false /*asynchronous*/,psessionEntry);
1541 limDeleteDphHashEntry(pMac, pStaDs->staAddr, aid,psessionEntry);
1542
1543 //Send indication.
1544 ibss_status_chg_notify( pMac, pTempNode->peerMacAddr, staIndex,
1545 ucUcastSig, ucBcastSig,
1546 eWNI_SME_IBSS_PEER_DEPARTED_IND,
1547 psessionEntry->smeSessionId );
1548 }
1549 if(pTempNode == pMac->lim.gLimIbssPeerList)
1550 {
1551 pMac->lim.gLimIbssPeerList = pTempNode->next;
1552 pPrevNode = pMac->lim.gLimIbssPeerList;
1553 }
1554 else
1555 pPrevNode->next = pTempNode->next;
1556
1557 palFreeMemory(pMac->hHdd,pTempNode);
1558 pMac->lim.gLimNumIbssPeers--;
1559
1560 pTempNode = pTempNextNode; //Since we deleted current node, prevNode remains same.
1561 continue;
1562 }
1563 }
1564
1565 pPrevNode = pTempNode;
1566 pTempNode = pTempNextNode;
1567 }
1568
1569 /** General IBSS Activity Monitor, check if in IBSS Mode we are received any Beacons */
1570 if(pMac->lim.gLimNumIbssPeers)
1571 {
1572 if(psessionEntry->LimRxedBeaconCntDuringHB < MAX_NO_BEACONS_PER_HEART_BEAT_INTERVAL)
1573 pMac->lim.gLimHeartBeatBeaconStats[psessionEntry->LimRxedBeaconCntDuringHB]++;
1574 else
1575 pMac->lim.gLimHeartBeatBeaconStats[0]++;
1576
1577 limReactivateHeartBeatTimer(pMac, psessionEntry);
1578
1579 // Reset number of beacons received
1580 limResetHBPktCount(psessionEntry);
1581 return;
1582 }
1583 else
1584 {
1585
1586 PELOGW(limLog(pMac, LOGW, FL("Heartbeat Failure\n"));)
1587 pMac->lim.gLimHBfailureCntInLinkEstState++;
1588
1589 if (psessionEntry->limIbssActive == true)
1590 {
1591 // We don't receive Beacon frames from any
1592 // other STA in IBSS. Announce IBSS inactive
1593 // to Roaming algorithm
1594 PELOGW(limLog(pMac, LOGW, FL("Alone in IBSS\n"));)
1595 psessionEntry->limIbssActive = false;
1596
1597 limSendSmeWmStatusChangeNtf(pMac, eSIR_SME_IBSS_INACTIVE,
1598 NULL, 0, psessionEntry->smeSessionId);
1599 }
1600 }
1601}
1602
1603
1604/** -------------------------------------------------------------
1605\fn limIbssDecideProtectionOnDelete
1606\brief Decides all the protection related information.
1607\
1608\param tpAniSirGlobal pMac
1609\param tSirMacAddr peerMacAddr
1610\param tpUpdateBeaconParams pBeaconParams
1611\return None
1612 -------------------------------------------------------------*/
1613void
1614limIbssDecideProtectionOnDelete(tpAniSirGlobal pMac,
1615 tpDphHashNode pStaDs, tpUpdateBeaconParams pBeaconParams, tpPESession psessionEntry)
1616{
1617 tANI_U32 phyMode;
1618 tHalBitVal erpEnabled = eHAL_CLEAR;
1619 tSirRFBand rfBand = SIR_BAND_UNKNOWN;
1620 tANI_U32 i;
1621
1622 if(NULL == pStaDs)
1623 return;
1624
1625 limGetRfBand(pMac, &rfBand, psessionEntry);
1626 if(SIR_BAND_2_4_GHZ == rfBand)
1627 {
1628 limGetPhyMode(pMac, &phyMode, psessionEntry);
1629 erpEnabled = pStaDs->erpEnabled;
1630 //we are HT or 11G and 11B station is getting deleted.
Jeff Johnsone7245742012-09-05 17:12:55 -07001631 if ( ((phyMode == WNI_CFG_PHY_MODE_11G) || psessionEntry->htCapability)
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 && (erpEnabled == eHAL_CLEAR))
1633 {
1634 PELOGE(limLog(pMac, LOGE, FL("(%d) A legacy STA is disassociated. Addr is "),
1635 psessionEntry->gLim11bParams.numSta);
1636 limPrintMacAddr(pMac, pStaDs->staAddr, LOGE);)
1637 if (psessionEntry->gLim11bParams.numSta > 0)
1638 {
1639 for (i=0; i<LIM_PROT_STA_CACHE_SIZE; i++)
1640 {
1641 if (pMac->lim.protStaCache[i].active)
1642 {
1643 if (palEqualMemory( pMac->hHdd,pMac->lim.protStaCache[i].addr,
1644 pStaDs->staAddr, sizeof(tSirMacAddr)))
1645 {
1646 psessionEntry->gLim11bParams.numSta--;
1647 pMac->lim.protStaCache[i].active = false;
1648 break;
1649 }
1650 }
1651 }
1652 }
1653
1654 if (psessionEntry->gLim11bParams.numSta == 0)
1655 {
1656 PELOGE(limLog(pMac, LOGE, FL("No more 11B STA exists. Disable protection. \n"));)
1657 limIbssSetProtection(pMac, false, pBeaconParams,psessionEntry);
1658 }
1659 }
1660 }
1661}