blob: 9385f16a4278aaaea8dd83a4fe8e69dc1d075873 [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 schBeaconGen.cc contains beacon generation related
25 * functions
26 *
27 * Author: Sandesh Goel
28 * Date: 02/25/02
29 * History:-
30 * Date Modified by Modification Information
31 * --------------------------------------------------------------------
32 *
33 */
34
35#include "palTypes.h"
36#include "wniCfgAp.h"
37#include "aniGlobal.h"
38#include "sirMacProtDef.h"
39
40#include "limUtils.h"
41#include "limApi.h"
42
43#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
44#include "halCommonApi.h"
45#include "halDataStruct.h"
46#endif
47
48#include "halMsgApi.h"
49#include "cfgApi.h"
50#include "pmmApi.h"
51#include "schApi.h"
52
53#include "parserApi.h"
54
55#include "schDebug.h"
56
57//
58// March 15, 2006
59// Temporarily (maybe for all of Alpha-1), assuming TIM = 0
60//
61
62const tANI_U8 P2pOui[] = {0x50, 0x6F, 0x9A, 0x9};
63
64#ifdef ANI_PRODUCT_TYPE_AP
65
66static void
67specialBeaconProcessing(tpAniSirGlobal pMac, tANI_U32 beaconSize);
68#endif
69
70#if defined(WLAN_SOFTAP_FEATURE) && defined(WLAN_FEATURE_P2P)
71tSirRetStatus schGetP2pIeOffset(tANI_U8 *pExtraIe, tANI_U32 extraIeLen, tANI_U16 *pP2pIeOffset)
72{
73 tSirRetStatus status = eSIR_FAILURE;
74 *pP2pIeOffset = 0;
75
76 // Extra IE is not present
77 if(0 == extraIeLen)
78 {
79 return status;
80 }
81
82 // Calculate the P2P IE Offset
83 do
84 {
85 if(*pExtraIe == 0xDD)
86 {
87 if(palEqualMemory(NULL, (void *)(pExtraIe+2), &P2pOui, sizeof(P2pOui)))
88 {
89 (*pP2pIeOffset)++;
90 status = eSIR_SUCCESS;
91 break;
92 }
93 }
94
95 (*pP2pIeOffset)++;
96 pExtraIe++;
97 }while(--extraIeLen > 0);
98
99 return status;
100}
101#endif
102
103tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry,
104 tANI_U8 *pFrame, tANI_U32 maxBeaconSize,
105 tANI_U32 *nBytes)
106{
107 tSirRetStatus status = eSIR_FAILURE;
108 tANI_U32 present, len;
109 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN];
110
111 if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG,
112 &present)) != eSIR_SUCCESS)
113 {
114 limLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG"));
115 return status;
116 }
117
118 if(present)
119 {
120 if((status = wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA,
121 &len)) != eSIR_SUCCESS)
122 {
123 limLog(pMac, LOGP,
124 FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length"));
125 return status;
126 }
127
128 if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len &&
129 ((len + *nBytes) <= maxBeaconSize))
130 {
131 if((status = wlan_cfgGetStr(pMac,
132 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len))
133 == eSIR_SUCCESS)
134 {
135#ifdef WLAN_FEATURE_P2P
136 tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len);
137 if(pP2pIe != NULL)
138 {
139 tANI_U8 noaLen = 0;
140 tANI_U8 noaStream[SIR_MAX_NOA_ATTR_LEN + SIR_P2P_IE_HEADER_LEN];
141 //get NoA attribute stream P2P IE
142 noaLen = limGetNoaAttrStream(pMac, noaStream, psessionEntry);
143 if(noaLen)
144 {
145 if(noaLen + len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN)
146 {
147 vos_mem_copy(&addIE[len], noaStream, noaLen);
148 len += noaLen;
149 /* Update IE Len */
150 pP2pIe[1] += noaLen;
151 }
152 else
153 {
154 limLog(pMac, LOGE,
155 FL("Not able to insert NoA because of length constraint"));
156 }
157 }
158 }
159#endif
160 vos_mem_copy(pFrame, &addIE[0], len);
161 *nBytes = *nBytes + len;
162 }
163 }
164 }
165
166 return status;
167}
168
169// --------------------------------------------------------------------
170/**
171 * schSetFixedBeaconFields
172 *
173 * FUNCTION:
174 *
175 * LOGIC:
176 *
177 * ASSUMPTIONS:
178 *
179 * NOTE:
180 *
181 * @param None
182 * @return None
183 */
184
185tSirRetStatus schSetFixedBeaconFields(tpAniSirGlobal pMac,tpPESession psessionEntry)
186{
187 tpAniBeaconStruct pBeacon = (tpAniBeaconStruct)
188 pMac->sch.schObject.gSchBeaconFrameBegin;
189 tpSirMacMgmtHdr mac;
190 tANI_U16 offset;
191 tANI_U8 *ptr;
192 tDot11fBeacon1 bcn1;
193 tDot11fBeacon2 bcn2;
194 tANI_U32 i, nStatus, nBytes;
195 tANI_U32 wpsApEnable=0, tmp;
196#ifdef WLAN_SOFTAP_FEATURE
197 tDot11fIEWscProbeRes WscProbeRes;
198#ifdef WLAN_FEATURE_P2P
199 tANI_U8 *pExtraIe = NULL;
200 tANI_U32 extraIeLen =0;
201 tANI_U16 extraIeOffset = 0;
202 tANI_U16 p2pIeOffset = 0;
203 tSirRetStatus status = eSIR_SUCCESS;
204#endif
205#endif
206
207 PELOG1(schLog(pMac, LOG1, FL("Setting fixed beacon fields\n"));)
208
209 /*
210 * First set the fixed fields
211 */
212
213 // set the TFP headers
214
215 // set the mac header
216 palZeroMemory( pMac->hHdd, ( tANI_U8*) &pBeacon->macHdr, sizeof( tSirMacMgmtHdr ) );
217 mac = (tpSirMacMgmtHdr) &pBeacon->macHdr;
218 mac->fc.type = SIR_MAC_MGMT_FRAME;
219 mac->fc.subType = SIR_MAC_MGMT_BEACON;
220
221 for (i=0; i<6; i++)
222 mac->da[i] = 0xff;
223
224 /* Knocking out Global pMac update */
225 /* limGetMyMacAddr(pMac, mac->sa); */
226 /* limGetBssid(pMac, mac->bssId); */
227
228 palCopyMemory(pMac->hHdd, mac->sa, psessionEntry->selfMacAddr, sizeof(psessionEntry->selfMacAddr));
229 palCopyMemory(pMac->hHdd, mac->bssId, psessionEntry->bssId, sizeof (psessionEntry->bssId));
230
231 mac->fc.fromDS = 0;
232 mac->fc.toDS = 0;
233
234 /*
235 * Now set the beacon body
236 */
237
238 palZeroMemory( pMac->hHdd, ( tANI_U8*) &bcn1, sizeof( bcn1 ) );
239
240 // Skip over the timestamp (it'll be updated later).
241
242 bcn1.BeaconInterval.interval = pMac->sch.schObject.gSchBeaconInterval;
243 PopulateDot11fCapabilities( pMac, &bcn1.Capabilities, psessionEntry );
244 if (psessionEntry->ssidHidden)
245 {
246 bcn1.SSID.present = 1; //rest of the fileds are 0 for hidden ssid
247 }
248 else
249 {
250 PopulateDot11fSSID( pMac, &psessionEntry->ssId, &bcn1.SSID );
251 }
252
253 PopulateDot11fSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL, &bcn1.SuppRates,psessionEntry);
254 PopulateDot11fDSParams( pMac, &bcn1.DSParams, psessionEntry->currentOperChannel, psessionEntry);
255 PopulateDot11fIBSSParams( pMac, &bcn1.IBSSParams,psessionEntry);
256
257 offset = sizeof( tAniBeaconStruct );
258 ptr = pMac->sch.schObject.gSchBeaconFrameBegin + offset;
259
260#ifdef WLAN_SOFTAP_FEATURE
261 if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
262 && (psessionEntry->proxyProbeRspEn))
263 {
264 /* Initialize the default IE bitmap to zero */
265 palZeroMemory( pMac->hHdd, ( tANI_U8* )&(psessionEntry->DefProbeRspIeBitmap), (sizeof( tANI_U32 ) * 8));
266
267 /* Initialize the default IE bitmap to zero */
268 palZeroMemory( pMac->hHdd, ( tANI_U8* )&(psessionEntry->probeRespFrame), sizeof(psessionEntry->probeRespFrame));
269
270 /* Can be efficiently updated whenever new IE added in Probe response in future */
271 limUpdateProbeRspTemplateIeBitmapBeacon1(pMac,&bcn1,&psessionEntry->DefProbeRspIeBitmap[0],
272 &psessionEntry->probeRespFrame);
273 }
274#endif
275
276 nStatus = dot11fPackBeacon1( pMac, &bcn1, ptr,
277 SCH_MAX_BEACON_SIZE - offset,
278 &nBytes );
279 if ( DOT11F_FAILED( nStatus ) )
280 {
281 schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon1 (0x%0"
282 "8x.).\n"), nStatus );
283 return eSIR_FAILURE;
284 }
285 else if ( DOT11F_WARNED( nStatus ) )
286 {
287 schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
288 "t11fBeacon1 (0x%08x.).\n"), nStatus );
289 }
290 /*changed to correct beacon corruption */
291 palZeroMemory( pMac->hHdd, ( tANI_U8*) &bcn2, sizeof( bcn2 ) );
292 pMac->sch.schObject.gSchBeaconOffsetBegin = offset + ( tANI_U16 )nBytes;
293 schLog( pMac, LOG1, FL("Initialized beacon begin, offset %d\n"), offset );
294
295 /*
296 * Initialize the 'new' fields at the end of the beacon
297 */
298
299
300 PopulateDot11fCountry( pMac, &bcn2.Country, psessionEntry);
301 if(bcn1.Capabilities.qos)
302 {
303 PopulateDot11fEDCAParamSet( pMac, &bcn2.EDCAParamSet, psessionEntry);
304 }
305
Jeff Johnsone7245742012-09-05 17:12:55 -0700306 if(psessionEntry->lim11hEnable)
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 {
308 PopulateDot11fPowerConstraints( pMac, &bcn2.PowerConstraints );
309 PopulateDot11fTPCReport( pMac, &bcn2.TPCReport, psessionEntry);
310 }
311
312#ifdef ANI_PRODUCT_TYPE_AP
Jeff Johnsone7245742012-09-05 17:12:55 -0700313 if( psessionEntry->lim11hEnable && (eLIM_QUIET_RUNNING == psessionEntry->gLimSpecMgmt.quietState))
Jeff Johnson295189b2012-06-20 16:38:30 -0700314 {
315 PopulateDot11fQuiet( pMac, &bcn2.Quiet );
316 }
317
318 /* If 11h is enabled, and AP is in the state of changing either the
319 * primary channel, or both primary & secondary channel, and the
320 * channel switch count is still being decremented, then AP shall
321 * populate the 802.11h channel switch IE in its Beacons and Probe
322 * Responses.
323 */
Jeff Johnsone7245742012-09-05 17:12:55 -0700324 if ( (psessionEntry->lim11hEnable) &&
325 (psessionEntry->gLimChannelSwitch.switchCount != 0) &&
326 (psessionEntry->gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING))
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700329 PopulateDot11fChanSwitchAnn( pMac, &bcn2.ChanSwitchAnn, psessionEntry );
330 PopulateDot11fExtChanSwitchAnn(pMac, &bcn2.ExtChanSwitchAnn, psessionEntry );
Jeff Johnson295189b2012-06-20 16:38:30 -0700331 }
332#endif
333
334 if (psessionEntry->dot11mode != WNI_CFG_DOT11_MODE_11B)
335 PopulateDot11fERPInfo( pMac, &bcn2.ERPInfo, psessionEntry );
336
Jeff Johnsone7245742012-09-05 17:12:55 -0700337 if(psessionEntry->htCapability)
Jeff Johnson295189b2012-06-20 16:38:30 -0700338 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700339 PopulateDot11fHTCaps( pMac, psessionEntry, &bcn2.HTCaps );
Jeff Johnson295189b2012-06-20 16:38:30 -0700340#ifdef WLAN_SOFTAP_FEATURE
341 PopulateDot11fHTInfo( pMac, &bcn2.HTInfo, psessionEntry );
342#else
343 PopulateDot11fHTInfo( pMac, &bcn2.HTInfo );
344#endif
345 }
Jeff Johnsone7245742012-09-05 17:12:55 -0700346#ifdef WLAN_FEATURE_11AC
347 if(psessionEntry->vhtCapability)
348 {
349 limLog( pMac, LOGW, FL("Populate VHT IEs in Beacon\n"));
350 PopulateDot11fVHTCaps( pMac, &bcn2.VHTCaps );
351 PopulateDot11fVHTOperation( pMac, &bcn2.VHTOperation);
352 // we do not support multi users yet
353 //PopulateDot11fVHTExtBssLoad( pMac, &bcn2.VHTExtBssLoad);
Mohit Khanna4a70d262012-09-11 16:30:12 -0700354 PopulateDot11fExtCap( pMac, &bcn2.ExtCap);
355 if(psessionEntry->gLimOperatingMode.present)
356 PopulateDot11fOperatingMode( pMac, &bcn2.OperatingMode, psessionEntry );
Jeff Johnsone7245742012-09-05 17:12:55 -0700357 }
358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700359
360 PopulateDot11fExtSuppRates( pMac, POPULATE_DOT11F_RATES_OPERATIONAL,
361 &bcn2.ExtSuppRates, psessionEntry );
362
363 if( psessionEntry->pLimStartBssReq != NULL )
364 {
365 PopulateDot11fWPA( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
366 &bcn2.WPA );
367 PopulateDot11fRSN( pMac, &psessionEntry->pLimStartBssReq->rsnIE,
368 &bcn2.RSN );
369 }
370
371 if(psessionEntry->limWmeEnabled)
372 {
373 PopulateDot11fWMM( pMac, &bcn2.WMMInfoAp, &bcn2.WMMParams, &bcn2.WMMCaps, psessionEntry);
374 }
375#ifdef WLAN_SOFTAP_FEATURE
376 if(psessionEntry->limSystemRole == eLIM_AP_ROLE)
377 {
378 if(psessionEntry->wps_state != SAP_WPS_DISABLED)
379 {
380 PopulateDot11fBeaconWPSIEs( pMac, &bcn2.WscBeacon, psessionEntry);
381 }
382 }
383 else
384 {
385#endif
386 if (wlan_cfgGetInt(pMac, (tANI_U16) WNI_CFG_WPS_ENABLE, &tmp) != eSIR_SUCCESS)
387 limLog(pMac, LOGP,"Failed to cfg get id %d\n", WNI_CFG_WPS_ENABLE );
388
389 wpsApEnable = tmp & WNI_CFG_WPS_ENABLE_AP;
390
391 if (wpsApEnable)
392 {
393 PopulateDot11fWsc(pMac, &bcn2.WscBeacon);
394 }
395
396 if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN)
397 {
398 PopulateDot11fWscRegistrarInfo(pMac, &bcn2.WscBeacon);
399 pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_IN_PROGRESS;
400 }
401
402 if (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END)
403 {
404 DePopulateDot11fWscRegistrarInfo(pMac, &bcn2.WscBeacon);
405 pMac->lim.wscIeInfo.wscEnrollmentState = eLIM_WSC_ENROLL_NOOP;
406 }
407#ifdef WLAN_SOFTAP_FEATURE
408 }
409#endif
410
411#ifdef WLAN_SOFTAP_FEATURE
412 if((psessionEntry->limSystemRole == eLIM_AP_ROLE)
413 && (psessionEntry->proxyProbeRspEn))
414 {
415 /* Can be efficiently updated whenever new IE added in Probe response in future */
416 limUpdateProbeRspTemplateIeBitmapBeacon2(pMac,&bcn2,&psessionEntry->DefProbeRspIeBitmap[0],
417 &psessionEntry->probeRespFrame);
418
419 /* update probe response WPS IE instead of beacon WPS IE
420 * */
421 if(psessionEntry->wps_state != SAP_WPS_DISABLED)
422 {
423 if(psessionEntry->APWPSIEs.SirWPSProbeRspIE.FieldPresent)
424 {
425 PopulateDot11fProbeResWPSIEs(pMac, &WscProbeRes, psessionEntry);
426 }
427 else
428 {
429 WscProbeRes.present = 0;
430 }
431 if(WscProbeRes.present)
432 {
433 SetProbeRspIeBitmap(&psessionEntry->DefProbeRspIeBitmap[0],SIR_MAC_WPA_EID);
434 palCopyMemory(pMac->hHdd,
435 (void *)&psessionEntry->probeRespFrame.WscProbeRes,
436 (void *)&WscProbeRes,
437 sizeof(WscProbeRes));
438 }
439 }
440
441 }
442#endif
443
444 nStatus = dot11fPackBeacon2( pMac, &bcn2,
445 pMac->sch.schObject.gSchBeaconFrameEnd,
446 SCH_MAX_BEACON_SIZE, &nBytes );
447 if ( DOT11F_FAILED( nStatus ) )
448 {
449 schLog( pMac, LOGE, FL("Failed to packed a tDot11fBeacon2 (0x%0"
450 "8x.).\n"), nStatus );
451 return eSIR_FAILURE;
452 }
453 else if ( DOT11F_WARNED( nStatus ) )
454 {
455 schLog( pMac, LOGE, FL("There were warnings while packing a tDo"
456 "t11fBeacon2 (0x%08x.).\n"), nStatus );
457 }
458
459#if defined(WLAN_SOFTAP_FEATURE) && defined(WLAN_FEATURE_P2P)
460 pExtraIe = pMac->sch.schObject.gSchBeaconFrameEnd + nBytes;
461 extraIeOffset = nBytes;
462#endif
463
464 //TODO: Append additional IE here.
465 schAppendAddnIE(pMac, psessionEntry,
466 pMac->sch.schObject.gSchBeaconFrameEnd + nBytes,
467 SCH_MAX_BEACON_SIZE, &nBytes);
468
469 pMac->sch.schObject.gSchBeaconOffsetEnd = ( tANI_U16 )nBytes;
470
471#if defined(WLAN_SOFTAP_FEATURE) && defined(WLAN_FEATURE_P2P)
472 extraIeLen = nBytes - extraIeOffset;
473
474 //Get the p2p Ie Offset
475 status = schGetP2pIeOffset(pExtraIe, extraIeLen, &p2pIeOffset);
476
477 if(eSIR_SUCCESS == status)
478 {
479 //Update the P2P Ie Offset
480 pMac->sch.schObject.p2pIeOffset =
481 pMac->sch.schObject.gSchBeaconOffsetBegin + TIM_IE_SIZE +
482 extraIeOffset + p2pIeOffset;
483 }
484 else
485 {
486 pMac->sch.schObject.p2pIeOffset = 0;
487 }
488#endif
489
490 schLog( pMac, LOG1, FL("Initialized beacon end, offset %d\n"),
491 pMac->sch.schObject.gSchBeaconOffsetEnd );
492
493 pMac->sch.schObject.fBeaconChanged = 1;
494
495 return eSIR_SUCCESS;
496}
497
498#ifdef WLAN_SOFTAP_FEATURE
499void limUpdateProbeRspTemplateIeBitmapBeacon1(tpAniSirGlobal pMac,
500 tDot11fBeacon1* beacon1,
501 tANI_U32* DefProbeRspIeBitmap,
502 tDot11fProbeResponse* prb_rsp)
503{
504 prb_rsp->BeaconInterval = beacon1->BeaconInterval;
505 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->Capabilities,
506 (void *)&beacon1->Capabilities,
507 sizeof(beacon1->Capabilities));
508
509 /* SSID */
510 if(beacon1->SSID.present)
511 {
512 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_SSID_EID);
513 /* populating it , because probe response has to go with SSID even in hidden case */
514 PopulateDot11fSSID2( pMac, &prb_rsp->SSID );
515 }
516 /* supported rates */
517 if(beacon1->SuppRates.present)
518 {
519 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RATESET_EID);
520 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->SuppRates,
521 (void *)&beacon1->SuppRates,
522 sizeof(beacon1->SuppRates));
523
524 }
525 /* DS Parameter set */
526 if(beacon1->DSParams.present)
527 {
528 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_DS_PARAM_SET_EID);
529 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->DSParams,
530 (void *)&beacon1->DSParams,
531 sizeof(beacon1->DSParams));
532
533 }
534
535 /* IBSS params will not be present in the Beacons transmitted by AP */
536}
537
538void limUpdateProbeRspTemplateIeBitmapBeacon2(tpAniSirGlobal pMac,
539 tDot11fBeacon2* beacon2,
540 tANI_U32* DefProbeRspIeBitmap,
541 tDot11fProbeResponse* prb_rsp)
542{
543 /* IBSS parameter set - will not be present in probe response tx by AP */
544 /* country */
545 if(beacon2->Country.present)
546 {
547 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_COUNTRY_EID);
548 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->Country,
549 (void *)&beacon2->Country,
550 sizeof(beacon2->Country));
551
552 }
553 /* Power constraint */
554 if(beacon2->PowerConstraints.present)
555 {
556 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_PWR_CONSTRAINT_EID);
557 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->PowerConstraints,
558 (void *)&beacon2->PowerConstraints,
559 sizeof(beacon2->PowerConstraints));
560
561 }
562 /* Channel Switch Annoouncement SIR_MAC_CHNL_SWITCH_ANN_EID */
563 if(beacon2->ChanSwitchAnn.present)
564 {
565 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_CHNL_SWITCH_ANN_EID);
566 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->ChanSwitchAnn,
567 (void *)&beacon2->ChanSwitchAnn,
568 sizeof(beacon2->ChanSwitchAnn));
569
570 }
571 /* ERP information */
572 if(beacon2->ERPInfo.present)
573 {
574 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_ERP_INFO_EID);
575 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->ERPInfo,
576 (void *)&beacon2->ERPInfo,
577 sizeof(beacon2->ERPInfo));
578
579 }
580 /* Extended supported rates */
581 if(beacon2->ExtSuppRates.present)
582 {
583 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EXTENDED_RATE_EID);
584 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->ExtSuppRates,
585 (void *)&beacon2->ExtSuppRates,
586 sizeof(beacon2->ExtSuppRates));
587
588 }
589
590 /* WPA */
591 if(beacon2->WPA.present)
592 {
593 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
594 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->WPA,
595 (void *)&beacon2->WPA,
596 sizeof(beacon2->WPA));
597
598 }
599
600 /* RSN */
601 if(beacon2->RSN.present)
602 {
603 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_RSN_EID);
604 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->RSN,
605 (void *)&beacon2->RSN,
606 sizeof(beacon2->RSN));
607
608 }
609/*
610 // BSS load
611 if(beacon2->QBSSLoad.present)
612 {
613 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_QBSS_LOAD_EID);
614 }
615*/
616 /* EDCA Parameter set */
617 if(beacon2->EDCAParamSet.present)
618 {
619 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_EDCA_PARAM_SET_EID);
620 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->EDCAParamSet,
621 (void *)&beacon2->EDCAParamSet,
622 sizeof(beacon2->EDCAParamSet));
623
624 }
625 /* Vendor specific - currently no vendor specific IEs added */
626 /* Requested IEs - currently we are not processing this will be added later */
627 //HT capability IE
628 if(beacon2->HTCaps.present)
629 {
630 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_CAPABILITIES_EID);
631 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->HTCaps,
632 (void *)&beacon2->HTCaps,
633 sizeof(beacon2->HTCaps));
634 }
635 // HT Info IE
636 if(beacon2->HTInfo.present)
637 {
638 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_HT_INFO_EID);
639 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->HTInfo,
640 (void *)&beacon2->HTInfo,
641 sizeof(beacon2->HTInfo));
642 }
643
Jeff Johnsone7245742012-09-05 17:12:55 -0700644#ifdef WLAN_FEATURE_11AC
645 if(beacon2->VHTCaps.present)
646 {
647 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_CAPABILITIES_EID);
648 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTCaps,
649 (void *)&beacon2->VHTCaps,
650 sizeof(beacon2->VHTCaps));
651 }
652 if(beacon2->VHTOperation.present)
653 {
654 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_OPERATION_EID);
655 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTOperation,
656 (void *)&beacon2->VHTOperation,
657 sizeof(beacon2->VHTOperation));
658 }
659 if(beacon2->VHTExtBssLoad.present)
660 {
661 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_VHT_EXT_BSS_LOAD_EID);
662 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->VHTExtBssLoad,
663 (void *)&beacon2->VHTExtBssLoad,
664 sizeof(beacon2->VHTExtBssLoad));
665 }
666#endif
667
Jeff Johnson295189b2012-06-20 16:38:30 -0700668 //WMM IE
669 if(beacon2->WMMParams.present)
670 {
671 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
672 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->WMMParams,
673 (void *)&beacon2->WMMParams,
674 sizeof(beacon2->WMMParams));
675 }
676 //WMM capability - most of the case won't be present
677 if(beacon2->WMMCaps.present)
678 {
679 SetProbeRspIeBitmap(DefProbeRspIeBitmap,SIR_MAC_WPA_EID);
680 palCopyMemory(pMac->hHdd,(void *)&prb_rsp->WMMCaps,
681 (void *)&beacon2->WMMCaps,
682 sizeof(beacon2->WMMCaps));
683 }
684
685}
686
687void SetProbeRspIeBitmap(tANI_U32* IeBitmap,tANI_U32 pos)
688{
689 tANI_U32 index,temp;
690
691 index = pos >> 5;
692 if(index >= 8 )
693 {
694 return;
695 }
696 temp = IeBitmap[index];
697
698 temp |= 1 << (pos & 0x1F);
699
700 IeBitmap[index] = temp;
701}
702
703#endif
704
705#ifdef ANI_PRODUCT_TYPE_AP
706
707//----------------------------
708/**
709 * @function : schUpdateCfpParam
710 * @brief : Generate the CFP Parameter Set
711 *
712 * @param : pMac - tpAniSirGlobal
713 * ptr - Pointer to the BeaconFrame
714 * pbeaconSize - The beaconSize
715 *
716 * @return : Return the Updated Ptrlocation
717 */
718static tANI_U8 *
719__schUpdateCfpParam(tpAniSirGlobal pMac, tANI_U8 *ptr, tANI_U32 *pbeaconSize)
720{
721 tANI_U32 val;
722
723 *ptr++ = SIR_MAC_CF_PARAM_SET_EID;
724 *ptr++ = SIR_MAC_CF_PARAM_SET_EID_MIN;
725
726 wlan_cfgGetInt(pMac, WNI_CFG_CFP_PERIOD, &val);
727 if (++pMac->sch.schObject.gSchCFPCount == val)
728 pMac->sch.schObject.gSchCFPCount = 0;
729
730 *ptr++ = pMac->sch.schObject.gSchCFPCount;
731 *ptr++ = (tANI_U8)val;
732
733 wlan_cfgGetInt(pMac, WNI_CFG_CFP_MAX_DURATION, &val);
734 pMac->sch.schObject.gSchCFPMaxDuration = (tANI_U8)val;
735
736 sirStoreU16(ptr, (tANI_U16)val);
737 ptr += 2;
738
739 if (pMac->sch.schObject.gSchCFPCount == 0)
740 pMac->sch.schObject.gSchCFPDurRemaining = pMac->sch.schObject.gSchCFPMaxDuration;
741 else if (pMac->sch.schObject.gSchCFPDurRemaining > pMac->sch.schObject.gSchBeaconInterval)
742 pMac->sch.schObject.gSchCFPDurRemaining -= pMac->sch.schObject.gSchBeaconInterval;
743 else
744 pMac->sch.schObject.gSchCFPDurRemaining = 0;
745
746 sirStoreU16(ptr, pMac->sch.schObject.gSchCFPDurRemaining);
747 ptr += 2;
748
749 (*pbeaconSize) += 2 + SIR_MAC_CF_PARAM_SET_EID_MIN;
750
751 return ptr;
752}
753
754#endif
755
756// --------------------------------------------------------------------
757/**
758 * writeBeaconToMemory
759 *
760 * FUNCTION:
761 *
762 * LOGIC:
763 *
764 * ASSUMPTIONS:
765 *
766 * NOTE:
767 *
768 * @param None
769 * @param size Size of the beacon to write to memory
770 * @param length Length field of the beacon to write to memory
771 * @return None
772 */
773
774void writeBeaconToMemory(tpAniSirGlobal pMac, tANI_U16 size, tANI_U16 length, tpPESession psessionEntry)
775{
776 tANI_U16 i;
777 tpAniBeaconStruct pBeacon;
778
779 // copy end of beacon only if length > 0
780 if (length > 0)
781 {
782 for (i=0; i < pMac->sch.schObject.gSchBeaconOffsetEnd; i++)
783 pMac->sch.schObject.gSchBeaconFrameBegin[size++] = pMac->sch.schObject.gSchBeaconFrameEnd[i];
784 }
785
786 // Update the beacon length
787 pBeacon = (tpAniBeaconStruct) pMac->sch.schObject.gSchBeaconFrameBegin;
788 // Do not include the beaconLength indicator itself
789 if (length == 0)
790 {
791 pBeacon->beaconLength = 0;
792 // Dont copy entire beacon, Copy length field alone
793 size = 4;
794 }
795 else
796 pBeacon->beaconLength = (tANI_U32) size - sizeof( tANI_U32 );
797
798 // write size bytes from gSchBeaconFrameBegin
799 PELOG2(schLog(pMac, LOG2, FL("Beacon size - %d bytes\n"), size);)
800 PELOG2(sirDumpBuf(pMac, SIR_SCH_MODULE_ID, LOG2, pMac->sch.schObject.gSchBeaconFrameBegin, size);)
801
802 if (! pMac->sch.schObject.fBeaconChanged)
803 return;
804
805 pMac->sch.gSchGenBeacon = 1;
806 if (pMac->sch.gSchGenBeacon)
807 {
808 pMac->sch.gSchBeaconsSent++;
809
810 //
811 // Copy beacon data to SoftMAC shared memory...
812 // Do this by sending a message to HAL
813 //
814
815 size = (size + 3) & (~3);
816 if( eSIR_SUCCESS != schSendBeaconReq( pMac, pMac->sch.schObject.gSchBeaconFrameBegin, size , psessionEntry))
817 PELOGE(schLog(pMac, LOGE, FL("schSendBeaconReq() returned an error (zsize %d)\n"), size);)
818 else
819 {
820 pMac->sch.gSchBeaconsWritten++;
821 }
822 }
823 pMac->sch.schObject.fBeaconChanged = 0;
824}
825
826// --------------------------------------------------------------------
827/**
828 * @function: SchProcessPreBeaconInd
829 *
830 * @brief : Process the PreBeacon Indication from the Lim
831 *
832 * ASSUMPTIONS:
833 *
834 * NOTE:
835 *
836 * @param : pMac - tpAniSirGlobal
837 *
838 * @return None
839 */
840
841void
842schProcessPreBeaconInd(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
843{
844 tpBeaconGenParams pMsg = (tpBeaconGenParams)limMsg->bodyptr;
845 tANI_U32 beaconSize = pMac->sch.schObject.gSchBeaconOffsetBegin;
846 tpPESession psessionEntry;
847 tANI_U8 sessionId;
848
849 if((psessionEntry = peFindSessionByBssid(pMac,pMsg->bssId, &sessionId))== NULL)
850 {
851 PELOGE(schLog(pMac, LOGE, FL("session lookup fails\n"));)
852 goto end;
853 }
854
855
856
857 // If SME is not in normal mode, no need to generate beacon
858 if (psessionEntry->limSmeState != eLIM_SME_NORMAL_STATE)
859 {
860 PELOGE(schLog(pMac, LOG1, FL("PreBeaconInd received in invalid state: %d\n"), psessionEntry->limSmeState);)
861 goto end;
862 }
863
864 switch(psessionEntry->limSystemRole){
865
866 case eLIM_STA_IN_IBSS_ROLE:
867 case eLIM_BT_AMP_AP_ROLE:
868 case eLIM_BT_AMP_STA_ROLE:
869 // generate IBSS parameter set
870 if(psessionEntry->statypeForBss == STA_ENTRY_SELF)
871 writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry);
872 else
873 PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry\n"));)
874 break;
875
876#ifdef WLAN_SOFTAP_FEATURE
877 case eLIM_AP_ROLE:{
878 tANI_U8 *ptr = &pMac->sch.schObject.gSchBeaconFrameBegin[pMac->sch.schObject.gSchBeaconOffsetBegin];
879 tANI_U16 timLength = 0;
880 if(psessionEntry->statypeForBss == STA_ENTRY_SELF){
881 pmmGenerateTIM(pMac, &ptr, &timLength, psessionEntry->dtimPeriod);
882 beaconSize += 2 + timLength;
883 writeBeaconToMemory(pMac, (tANI_U16) beaconSize, (tANI_U16)beaconSize, psessionEntry);
884 }
885 else
886 PELOGE(schLog(pMac, LOGE, FL("can not send beacon for PEER session entry\n"));)
887 }
888 break;
889#endif
890
891#ifdef ANI_PRODUCT_TYPE_AP
892 case eLIM_AP_ROLE:
893 {
894 tANI_U8 *ptr = &pMac->sch.schObject.gSchBeaconFrameBegin[pMac->sch.schObject.gSchBeaconOffsetBegin];
895 tANI_U16 timLength = 0;
896
897 if (pMac->sch.schObject.gSchCFPEnabled)
898 ptr = __schUpdateCfpParam( pMac, ptr, &beaconSize);
899
900 // generate TIM
901 pmmGenerateTIM(pMac, &ptr, &timLength);
902 beaconSize += 2 + timLength;
903
904 /**
905 * Safe to call this each time.
906 * Based on the requirement for updating the
907 * fixed beacon fields, this routine will
908 * appropriately update the fixed fields
909 */
910 specialBeaconProcessing(pMac, beaconSize);
911 writeBeaconToMemory(pMac, beaconSize, beaconSize, psessionEntry);
912 pmmHandleTimBasedDisassociation( pMac, psessionEntry );
913 }
914 break;
915#endif
916
917 default:
918 PELOGE(schLog(pMac, LOGE, FL("Error-PE has Receive PreBeconGenIndication when System is in %d role"),
919 psessionEntry->limSystemRole);)
920 }
921
922end:
923 palFreeMemory(pMac->hHdd, (void*)pMsg);
924
925}
926
927/**-------------------------------------------------------------
928 \fn specialBeaconProcessing
929 \brief To add/update channel switch IE/ Quiet IE in beacons.
930 And also to resume transmission and measurement after
931 switching the channel.
932
933 \param pMac
934 \param beaconSize Size of the beacon
935 \return NONE
936 --------------------------------------------------------------*/
937#ifdef ANI_PRODUCT_TYPE_AP
938
939static void
940specialBeaconProcessing( tpAniSirGlobal pMac, tANI_U32 beaconSize)
941{
942
943 tpPESession psessionEntry = &pMac->lim.gpSession[0]; //TBD-RAJESH HOW TO GET sessionEntry?????
944 tANI_BOOLEAN fBeaconChanged = eANI_BOOLEAN_FALSE;
945
946 fBeaconChanged = limUpdateQuietIEInBeacons( pMac );
947
948 if((pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_BEGIN) ||
949 (pMac->lim.wscIeInfo.wscEnrollmentState == eLIM_WSC_ENROLL_END))
950 {
951 fBeaconChanged = eANI_BOOLEAN_TRUE;
952 }
953
954
955 /*******************************
956 * Processing Channel Switch IE
957 *******************************/
958 if (pMac->lim.gLimSpecMgmt.dot11hChanSwState == eLIM_11H_CHANSW_RUNNING)
959 {
960 fBeaconChanged = eANI_BOOLEAN_TRUE;
961
962#if 0
963 // If the station doesn't support 11h or have link monitoring enabled,
964 // AP has to send disassoc frame to indicate station before going
965 // to new channel. Otherwise station wont connect to AP in new channel.
966 if (pMac->lim.gLimChannelSwitch.switchCount == 1)
967 {
968 if((pMac->lim.gLimChannelSwitch.state
969 == eLIM_CHANNEL_SWITCH_PRIMARY_ONLY) ||
970 (pMac->lim.gLimChannelSwitch.state
971 == eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY))
972 {
973 tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
974
975 limSendDisassocMgmtFrame(pMac,
976 eSIR_MAC_DISASSOC_LEAVING_BSS_REASON,
977 bcAddr);
978 }
979 }
980#endif
981 if (pMac->lim.gLimChannelSwitch.switchCount == 0)
982 {
983
984 /* length is set to 0, so that no beacon is transmitted without channel switch IE
985 * before switching to new channel */
986 pMac->sch.schObject.fBeaconChanged = 1;
987 writeBeaconToMemory(pMac, beaconSize, 0, psessionEntry);
988 schSetFixedBeaconFields(pMac,psessionEntry);
989
990 PELOG3(limLog(pMac, LOG3, FL("Channel switch state = %d\n"), pMac->lim.gLimChannelSwitch.state);)
991 switch(pMac->lim.gLimChannelSwitch.state)
992 {
993 case eLIM_CHANNEL_SWITCH_PRIMARY_ONLY:
994 limSwitchPrimaryChannel(pMac, pMac->lim.gLimChannelSwitch.primaryChannel);
995 break;
996 case eLIM_CHANNEL_SWITCH_SECONDARY_ONLY:
Jeff Johnsone7245742012-09-05 17:12:55 -0700997 limSwitchPrimarySecondaryChannel(pMac, psessionEntry,
Jeff Johnson295189b2012-06-20 16:38:30 -0700998 psessionEntry->currentOperChannel,
999 pMac->lim.gLimChannelSwitch.secondarySubBand);
1000 break;
1001 case eLIM_CHANNEL_SWITCH_PRIMARY_AND_SECONDARY:
Jeff Johnsone7245742012-09-05 17:12:55 -07001002 limSwitchPrimarySecondaryChannel(pMac, psessionEntry,
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 pMac->lim.gLimChannelSwitch.primaryChannel,
1004 pMac->lim.gLimChannelSwitch.secondarySubBand);
1005 break;
1006 case eLIM_CHANNEL_SWITCH_IDLE:
1007 PELOGE(schLog(pMac, LOGE, FL("incorrect state - CHANNEL_SWITCH_IDLE\n"));)
1008 break;
1009
1010 default:
1011 break;
1012 }
1013 pMac->lim.gLimChannelSwitch.state = eLIM_CHANNEL_SWITCH_IDLE;
1014
1015 limSendSmeRsp(pMac, eWNI_SME_SWITCH_CHL_RSP, eSIR_SME_SUCCESS);
1016
1017 limFrameTransmissionControl(pMac, eLIM_TX_BSS_BUT_BEACON, eLIM_RESUME_TX);
1018 /* Flag to indicate 11h channel switch is done. */
1019 pMac->lim.gLimSpecMgmt.dot11hChanSwState = eLIM_11H_CHANSW_INIT;
1020 pMac->lim.gLimSpecMgmt.quietState = eLIM_QUIET_INIT;
1021 LIM_SET_RADAR_DETECTED(pMac, eANI_BOOLEAN_FALSE);
1022
1023 if (pMac->lim.gpLimMeasReq)
1024 limReEnableLearnMode(pMac);
1025
1026 return;
1027 }
1028 }
1029
1030 if (fBeaconChanged)
1031 {
1032 schSetFixedBeaconFields(pMac,psessionEntry);
1033
1034 if (pMac->lim.gLimChannelSwitch.switchCount > 0)
1035 pMac->lim.gLimChannelSwitch.switchCount--;
1036 }
1037}
1038#endif
1039
1040