import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / mgmt / rlm.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rlm.c#2 $
3 */
4
5 /*! \file "rlm.c"
6 \brief
7
8 */
9
10
11
12 /*
13 ** $Log: rlm.c $
14 *
15 * 07 17 2012 yuche.tsai
16 * NULL
17 * Compile no error before trial run.
18 *
19 * 11 15 2011 cm.chang
20 * NULL
21 * Check length HT cap IE about RX associate request frame
22 *
23 * 11 10 2011 cm.chang
24 * NULL
25 * Modify debug message for XLOG
26 *
27 * 11 08 2011 cm.chang
28 * NULL
29 * Add RLM and CNM debug message for XLOG
30 *
31 * 11 03 2011 cm.chang
32 * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
33 * Fix preamble type of STA mode
34 *
35 * 10 25 2011 cm.chang
36 * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
37 * Not send ERP IE if peer STA is 802.11b-only
38 *
39 * 10 11 2011 cm.chang
40 * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
41 * Ignore HT OP IE if its length field is not valid
42 *
43 * 09 28 2011 cm.chang
44 * NULL
45 * Add length check to reduce possibility to adopt wrong IE
46 *
47 * 09 20 2011 cm.chang
48 * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
49 * Handle client mode about preamble type and slot time
50 *
51 * 09 01 2011 cm.chang
52 * [WCXRP00000971] [MT6620 Wi-Fi][Driver][FW] Not set Beacon timeout interval when CPTT
53 * Final channel number only adopts the field from assoc response
54 *
55 * 06 10 2011 cm.chang
56 * [WCXRP00000773] [MT6620 Wi-Fi][Driver] Workaround some AP fill primary channel field with its secondary channel
57 * If DS IE exists, ignore the primary channel field in HT OP IE
58 *
59 * 05 03 2011 cm.chang
60 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
61 * Fix compiling error
62 *
63 * 05 02 2011 cm.chang
64 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
65 * Refine range of valid channel number
66 *
67 * 05 02 2011 cm.chang
68 * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
69 * Check if channel is valided before record ing BSS channel
70 *
71 * 04 14 2011 cm.chang
72 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
73 * .
74 *
75 * 04 12 2011 cm.chang
76 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
77 * .
78 *
79 * 03 29 2011 cm.chang
80 * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning
81 * As CR title
82 *
83 * 01 24 2011 cm.chang
84 * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec is freed
85 * Process received 20/40 coexistence action frame for AP mode
86 *
87 * 12 13 2010 cp.wu
88 * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
89 * create branch for Wi-Fi driver v1.1
90 *
91 * 12 07 2010 cm.chang
92 * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
93 * 1. BSSINFO include RLM parameter
94 * 2. free all sta records when network is disconnected
95 *
96 * 12 07 2010 cm.chang
97 * [WCXRP00000238] MT6620 Wi-Fi][Driver][FW] Support regulation domain setting from NVRAM and supplicant
98 * 1. Country code is from NVRAM or supplicant
99 * 2. Change band definition in CMD/EVENT.
100 *
101 * 10 15 2010 cm.chang
102 * [WCXRP00000094] [MT6620 Wi-Fi][Driver] Connect to 2.4GHz AP, Driver crash.
103 * Add exception handle when no mgmt buffer in free build
104 *
105 * 10 08 2010 cm.chang
106 * NULL
107 * When 20M only setting, ignore OBSS IE
108 *
109 * 09 16 2010 cm.chang
110 * NULL
111 * Change conditional compiling options for BOW
112 *
113 * 09 10 2010 cm.chang
114 * NULL
115 * Always update Beacon content if FW sync OBSS info
116 *
117 * 09 03 2010 kevin.huang
118 * NULL
119 * Refine #include sequence and solve recursive/nested #include issue
120 *
121 * 08 24 2010 cm.chang
122 * NULL
123 * Support RLM initail channel of Ad-hoc, P2P and BOW
124 *
125 * 08 23 2010 cp.wu
126 * NULL
127 * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
128 *
129 * 08 23 2010 chinghwa.yu
130 * NULL
131 * Temporary add rlmUpdateParamByStaForBow() and rlmBssInitForBow().
132 *
133 * 08 23 2010 chinghwa.yu
134 * NULL
135 * Add CFG_ENABLE_BT_OVER_WIFI.
136 *
137 * 08 23 2010 chinghwa.yu
138 * NULL
139 * Update for BOW.
140 *
141 * 08 20 2010 cm.chang
142 * NULL
143 * Migrate RLM code to host from FW
144 *
145 * 08 02 2010 yuche.tsai
146 * NULL
147 * P2P Group Negotiation Code Check in.
148 *
149 * 07 26 2010 yuche.tsai
150 *
151 * Fix compile error while enabling WiFi Direct function.
152 *
153 * 07 21 2010 yuche.tsai
154 *
155 * Add P2P Scan & Scan Result Parsing & Saving.
156 *
157 * 07 19 2010 cm.chang
158 *
159 * Set RLM parameters and enable CNM channel manager
160 *
161 * 07 08 2010 cp.wu
162 *
163 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
164 *
165 * 07 08 2010 cp.wu
166 * [WPD00003833][MT6620 and MT5931] Driver migration
167 * take use of RLM module for parsing/generating HT IEs for 11n capability
168 *
169 * 07 08 2010 cm.chang
170 * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
171 * Check draft RLM code for HT cap
172 *
173 * 06 05 2010 cm.chang
174 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
175 * Fix channel ID definition in RFB status to primary channel instead of center channel
176 *
177 * 06 02 2010 cm.chang
178 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
179 * Add TX short GI compiling option
180 *
181 * 06 02 2010 chinghwa.yu
182 * [BORA00000563]Add WiFi CoEx BCM module
183 * Roll back to remove CFG_SUPPORT_BCM_TEST.
184 *
185 * 06 01 2010 chinghwa.yu
186 * [BORA00000563]Add WiFi CoEx BCM module
187 * Update BCM Test and RW configuration.
188 *
189 * 05 31 2010 cm.chang
190 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
191 * Add some compiling options to control 11n functions
192 *
193 * 05 28 2010 cm.chang
194 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
195 * Set RTS threshold of 2K bytes initially
196 *
197 * 05 18 2010 cm.chang
198 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
199 * Ad-hoc Beacon should not carry HT OP and OBSS IEs
200 *
201 * 05 07 2010 cm.chang
202 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
203 * Process 20/40 coexistence public action frame in AP mode
204 *
205 * 05 05 2010 cm.chang
206 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
207 * First draft support for 20/40M bandwidth for AP mode
208 *
209 * 04 24 2010 cm.chang
210 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
211 * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
212 *
213 * 04 22 2010 cm.chang
214 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
215 * First draft code to support protection in AP mode
216 *
217 * 04 13 2010 cm.chang
218 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
219 * Utilize status of swRfb to know channel number and band
220 *
221 * 04 07 2010 cm.chang
222 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
223 * Different invoking order for WTBL entry of associated AP
224 *
225 * 04 07 2010 cm.chang
226 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
227 * Add virtual test for OBSS scan
228 *
229 * 04 02 2010 cm.chang
230 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
231 * Process Beacon only ready for infra STA now
232 *
233 * 03 30 2010 cm.chang
234 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
235 * Support 2.4G OBSS scan
236 *
237 * 03 24 2010 cm.chang
238 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
239 * Not carry HT cap when being associated with b/g only AP
240 *
241 * 03 24 2010 wh.su
242 * [BORA00000605][WIFISYS] Phase3 Integration
243 * fixed some WHQL testing error.
244 *
245 * 03 15 2010 cm.chang
246 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
247 * Provide draft measurement and quiet functions
248 *
249 * 03 09 2010 cm.chang
250 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
251 * If bss is not 11n network, zero WTBL HT parameters
252 *
253 * 03 03 2010 cm.chang
254 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
255 * To support CFG_SUPPORT_BCM_STP
256 *
257 * 03 02 2010 cm.chang
258 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
259 * Generate HT IE only depending on own phyTypeSet
260 *
261 * 03 02 2010 cm.chang
262 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
263 * Not fill HT related IE if BssInfo does not include 11n phySet
264 *
265 * 03 01 2010 tehuang.liu
266 * [BORA00000569][WIFISYS] Phase 2 Integration Test
267 * To store field AMPDU Parameters in STA_REC
268 *
269 * 02 26 2010 cm.chang
270 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
271 * Enable RDG RX, but disable RDG TX for IOT and LongNAV
272 *
273 * 02 12 2010 cm.chang
274 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
275 * Use bss info array for concurrent handle
276 *
277 * 02 05 2010 kevin.huang
278 * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
279 * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
280 *
281 * 01 22 2010 cm.chang
282 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
283 * Support protection and bandwidth switch
284 *
285 * 01 07 2010 kevin.huang
286 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
287 * Modify the parameter of rlmRecAssocRspHtInfo function
288 *
289 * 12 18 2009 cm.chang
290 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
291 * .
292 *
293 * Dec 12 2009 mtk01104
294 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
295 * Fix prBssInfo->ucPrimaryChannel handle for assoc resp
296 *
297 * Dec 9 2009 mtk01104
298 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
299 * Add some function to process HT operation
300 *
301 * Nov 28 2009 mtk01104
302 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
303 * Call rlmStatisticsInit() to handle MIB counters
304 *
305 * Nov 18 2009 mtk01104
306 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
307 *
308 *
309 **
310 */
311
312 /*******************************************************************************
313 * C O M P I L E R F L A G S
314 ********************************************************************************
315 */
316
317 /*******************************************************************************
318 * E X T E R N A L R E F E R E N C E S
319 ********************************************************************************
320 */
321 #include "precomp.h"
322
323 /*******************************************************************************
324 * C O N S T A N T S
325 ********************************************************************************
326 */
327
328 /*******************************************************************************
329 * D A T A T Y P E S
330 ********************************************************************************
331 */
332
333 /*******************************************************************************
334 * P U B L I C D A T A
335 ********************************************************************************
336 */
337
338 /*******************************************************************************
339 * P R I V A T E D A T A
340 ********************************************************************************
341 */
342
343 /*******************************************************************************
344 * M A C R O S
345 ********************************************************************************
346 */
347
348 /*******************************************************************************
349 * F U N C T I O N D E C L A R A T I O N S
350 ********************************************************************************
351 */
352 static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
353
354 static VOID
355 rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
356
357 static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo);
358
359 static UINT_8
360 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter,
361 P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength);
362
363 static BOOLEAN
364 rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter,
365 P_BSS_INFO_T prBssInfo,
366 P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
367
368 static BOOLEAN
369 rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter,
370 P_BSS_INFO_T prBssInfo,
371 P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength);
372
373 static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo);
374
375 /*******************************************************************************
376 * F U N C T I O N S
377 ********************************************************************************
378 */
379
380 /*----------------------------------------------------------------------------*/
381 /*!
382 * \brief
383 *
384 * \param[in]
385 *
386 * \return none
387 */
388 /*----------------------------------------------------------------------------*/
389 VOID rlmFsmEventInit(P_ADAPTER_T prAdapter)
390 {
391 ASSERT(prAdapter);
392
393 /* Note: assume TIMER_T structures are reset to zero or stopped
394 * before invoking this function.
395 */
396
397 /* Initialize OBSS FSM */
398 rlmObssInit(prAdapter);
399 }
400
401 /*----------------------------------------------------------------------------*/
402 /*!
403 * \brief
404 *
405 * \param[in]
406 *
407 * \return none
408 */
409 /*----------------------------------------------------------------------------*/
410 VOID rlmFsmEventUninit(P_ADAPTER_T prAdapter)
411 {
412 P_BSS_INFO_T prBssInfo;
413 UINT_8 ucNetIdx;
414
415 ASSERT(prAdapter);
416
417 RLM_NET_FOR_EACH(ucNetIdx) {
418 prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
419 ASSERT(prBssInfo);
420
421 /* Note: all RLM timers will also be stopped.
422 * Now only one OBSS scan timer.
423 */
424 rlmBssReset(prAdapter, prBssInfo);
425 }
426 }
427
428 /*----------------------------------------------------------------------------*/
429 /*!
430 * \brief For probe request, association request
431 *
432 * \param[in]
433 *
434 * \return none
435 */
436 /*----------------------------------------------------------------------------*/
437 VOID rlmReqGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
438 {
439 P_BSS_INFO_T prBssInfo;
440 P_STA_RECORD_T prStaRec;
441
442 ASSERT(prAdapter);
443 ASSERT(prMsduInfo);
444
445 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
446 ASSERT(prBssInfo);
447
448 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
449
450 if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
451 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
452
453 rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
454 }
455 }
456
457 /*----------------------------------------------------------------------------*/
458 /*!
459 * \brief For probe request, association request
460 *
461 * \param[in]
462 *
463 * \return none
464 */
465 /*----------------------------------------------------------------------------*/
466 VOID rlmReqGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
467 {
468 P_BSS_INFO_T prBssInfo;
469 P_STA_RECORD_T prStaRec;
470
471 ASSERT(prAdapter);
472 ASSERT(prMsduInfo);
473
474 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
475 ASSERT(prBssInfo);
476
477 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
478
479 if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
480 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
481
482 rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
483 }
484 }
485
486 /*----------------------------------------------------------------------------*/
487 /*!
488 * \brief For probe response (GO, IBSS) and association response
489 *
490 * \param[in]
491 *
492 * \return none
493 */
494 /*----------------------------------------------------------------------------*/
495 VOID rlmRspGenerateHtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
496 {
497 P_BSS_INFO_T prBssInfo;
498 P_STA_RECORD_T prStaRec;
499
500 ASSERT(prAdapter);
501 ASSERT(prMsduInfo);
502 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
503
504 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
505 ASSERT(prBssInfo);
506
507 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
508
509 if (RLM_NET_IS_11N(prBssInfo) &&
510 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
511
512 rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
513 }
514 }
515
516 /*----------------------------------------------------------------------------*/
517 /*!
518 * \brief For probe response (GO, IBSS) and association response
519 *
520 * \param[in]
521 *
522 * \return none
523 */
524 /*----------------------------------------------------------------------------*/
525 VOID rlmRspGenerateExtCapIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
526 {
527 P_BSS_INFO_T prBssInfo;
528 P_STA_RECORD_T prStaRec;
529
530 ASSERT(prAdapter);
531 ASSERT(prMsduInfo);
532 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
533
534 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
535 ASSERT(prBssInfo);
536
537 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
538
539 if (RLM_NET_IS_11N(prBssInfo) &&
540 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
541
542 rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
543 }
544 }
545
546 /*----------------------------------------------------------------------------*/
547 /*!
548 * \brief For probe response (GO, IBSS) and association response
549 *
550 * \param[in]
551 *
552 * \return none
553 */
554 /*----------------------------------------------------------------------------*/
555 VOID rlmRspGenerateHtOpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
556 {
557 P_BSS_INFO_T prBssInfo;
558 P_STA_RECORD_T prStaRec;
559
560 ASSERT(prAdapter);
561 ASSERT(prMsduInfo);
562 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
563
564 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
565
566 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
567 ASSERT(prBssInfo);
568
569 if (RLM_NET_IS_11N(prBssInfo) &&
570 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
571
572 rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo);
573 }
574 }
575
576 /*----------------------------------------------------------------------------*/
577 /*!
578 * \brief For probe response (GO, IBSS) and association response
579 *
580 * \param[in]
581 *
582 * \return none
583 */
584 /*----------------------------------------------------------------------------*/
585 VOID rlmRspGenerateErpIE(P_ADAPTER_T prAdapter, P_MSDU_INFO_T prMsduInfo)
586 {
587 P_BSS_INFO_T prBssInfo;
588 P_STA_RECORD_T prStaRec;
589 P_IE_ERP_T prErpIe;
590
591 ASSERT(prAdapter);
592 ASSERT(prMsduInfo);
593 ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
594
595 prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
596
597 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
598 ASSERT(prBssInfo);
599
600 if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 &&
601 (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) {
602 prErpIe = (P_IE_ERP_T)
603 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
604
605 /* Add ERP IE */
606 prErpIe->ucId = ELEM_ID_ERP_INFO;
607 prErpIe->ucLength = 1;
608
609 prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ? ERP_INFO_USE_PROTECTION : 0;
610
611 if (prBssInfo->fgErpProtectMode) {
612 prErpIe->ucERP |= (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION);
613 }
614
615 /* Handle barker preamble */
616 if (!prBssInfo->fgUseShortPreamble) {
617 prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE;
618 }
619
620 ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP));
621
622 prMsduInfo->u2FrameLength += IE_SIZE(prErpIe);
623 }
624 }
625
626 /*----------------------------------------------------------------------------*/
627 /*!
628 * \brief
629 *
630 * \param[in]
631 *
632 * \return none
633 */
634 /*----------------------------------------------------------------------------*/
635 static VOID rlmFillHtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
636 {
637 P_IE_HT_CAP_T prHtCap;
638 P_SUP_MCS_SET_FIELD prSupMcsSet;
639 BOOLEAN fg40mAllowed;
640
641 ASSERT(prAdapter);
642 ASSERT(prBssInfo);
643 ASSERT(prMsduInfo);
644
645 #if 1
646 if (prMsduInfo->ucNetworkType == NETWORK_TYPE_P2P_INDEX) {
647 DBGLOG(AIS, WARN, ("Assoc:Force P2P BW to 20\n"));
648 prBssInfo->fgAssoc40mBwAllowed = FALSE;
649 }
650 #endif
651
652
653 fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
654
655 prHtCap = (P_IE_HT_CAP_T)
656 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
657
658 /* Add HT capabilities IE */
659 prHtCap->ucId = ELEM_ID_HT_CAP;
660 prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN;
661
662 prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL;
663 if (!fg40mAllowed) {
664 prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH |
665 HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M);
666 }
667 if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) {
668 prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
669 }
670
671 if (prAdapter->rWifiVar.u8SupportRxSgi20 == 2) {
672 prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M);
673 }
674 if (prAdapter->rWifiVar.u8SupportRxSgi40 == 2) {
675 prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M);
676 }
677 if (prAdapter->rWifiVar.u8SupportRxGf == 2) {
678 prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF);
679 }
680
681 prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL;
682
683 prSupMcsSet = &prHtCap->rSupMcsSet;
684 kalMemZero((PVOID) & prSupMcsSet->aucRxMcsBitmask[0], SUP_MCS_RX_BITMASK_OCTET_NUM);
685
686 prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7);
687
688 if (fg40mAllowed) {
689 prSupMcsSet->aucRxMcsBitmask[32 / 8] = BIT(0); /* MCS32 */
690 }
691 prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE;
692 prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL;
693
694 prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL;
695 if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
696 prHtCap->u2HtExtendedCap &= ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE);
697 }
698
699 prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL;
700
701 prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL;
702
703
704 ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP));
705
706 prMsduInfo->u2FrameLength += IE_SIZE(prHtCap);
707 }
708
709 /*----------------------------------------------------------------------------*/
710 /*!
711 * \brief
712 *
713 * \param[in]
714 *
715 * \return none
716 */
717 /*----------------------------------------------------------------------------*/
718 static VOID rlmFillExtCapIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
719 {
720 P_EXT_CAP_T prExtCap;
721 BOOLEAN fg40mAllowed;
722
723 ASSERT(prAdapter);
724 ASSERT(prMsduInfo);
725
726 fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
727
728 /* Add Extended Capabilities IE */
729 prExtCap = (P_EXT_CAP_T)
730 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
731
732 prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
733 prExtCap->ucLength = 1;
734 prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
735
736 if (!fg40mAllowed) {
737 prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT;
738 }
739
740 if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
741 prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
742 }
743
744 ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
745
746 prMsduInfo->u2FrameLength += IE_SIZE(prExtCap);
747 }
748
749 /*----------------------------------------------------------------------------*/
750 /*!
751 * \brief
752 *
753 * \param[in]
754 *
755 * \return none
756 */
757 /*----------------------------------------------------------------------------*/
758 static VOID rlmFillHtOpIE(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo, P_MSDU_INFO_T prMsduInfo)
759 {
760 P_IE_HT_OP_T prHtOp;
761 UINT_16 i;
762
763 ASSERT(prAdapter);
764 ASSERT(prBssInfo);
765 ASSERT(prMsduInfo);
766
767 prHtOp = (P_IE_HT_OP_T)
768 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
769
770 /* Add HT operation IE */
771 prHtOp->ucId = ELEM_ID_HT_OP;
772 prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN;
773
774 /* RIFS and 20/40 bandwidth operations are included */
775 prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
776 prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1;
777
778 /* Decide HT protection mode field */
779 if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) {
780 prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT;
781 } else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
782 prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER;
783 } else {
784 /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */
785 prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode;
786 }
787
788 if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) {
789 /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED
790 * Note: it will also be set in ad-hoc network
791 */
792 prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
793 }
794
795 if (0 /* Regulatory class 16 */ &&
796 prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
797 /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection
798 * although it is possible to have no protection by spec.
799 */
800 prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
801 }
802
803 prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3; /* To do: handle L-SIG TXOP */
804
805 /* No basic MCSx are needed temporarily */
806 for (i = 0; i < 16; i++) {
807 prHtOp->aucBasicMcsSet[i] = 0;
808 }
809
810 ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP));
811
812 prMsduInfo->u2FrameLength += IE_SIZE(prHtOp);
813 }
814
815 /*----------------------------------------------------------------------------*/
816 /*!
817 * \brief This function should be invoked to update parameters of associated AP.
818 * (Association response and Beacon)
819 *
820 * \param[in]
821 *
822 * \return none
823 */
824 /*----------------------------------------------------------------------------*/
825 static UINT_8
826 rlmRecIeInfoForClient(P_ADAPTER_T prAdapter,
827 P_BSS_INFO_T prBssInfo, PUINT_8 pucIE, UINT_16 u2IELength)
828 {
829 UINT_16 u2Offset;
830 P_STA_RECORD_T prStaRec;
831 P_IE_HT_CAP_T prHtCap;
832 P_IE_HT_OP_T prHtOp;
833 P_IE_OBSS_SCAN_PARAM_T prObssScnParam;
834 UINT_8 ucERP, ucPrimaryChannel;
835 #if CFG_SUPPORT_QUIET && 0
836 BOOLEAN fgHasQuietIE = FALSE;
837 #endif
838
839 ASSERT(prAdapter);
840 ASSERT(prBssInfo);
841 ASSERT(pucIE);
842
843 prStaRec = prBssInfo->prStaRecOfAP;
844 ASSERT(prStaRec);
845 if (!prStaRec) {
846 return 0;
847 }
848
849 prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
850 ucPrimaryChannel = 0;
851 prObssScnParam = NULL;
852
853 /* Note: HT-related members in staRec may not be zero before, so
854 * if following IE does not exist, they are still not zero.
855 * These HT-related parameters are vaild only when the corresponding
856 * BssInfo supports 802.11n, i.e., RLM_NET_IS_11N()
857 */
858 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
859 switch (IE_ID(pucIE)) {
860 case ELEM_ID_HT_CAP:
861 if (!RLM_NET_IS_11N(prBssInfo) ||
862 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
863 break;
864 }
865 prHtCap = (P_IE_HT_CAP_T) pucIE;
866 prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
867 prStaRec->fgSupMcs32 =
868 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE;
869
870 prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
871 prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
872 prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
873 prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
874 prStaRec->ucAselCap = prHtCap->ucAselCap;
875 break;
876
877 case ELEM_ID_HT_OP:
878 if (!RLM_NET_IS_11N(prBssInfo) || IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
879 break;
880 }
881 prHtOp = (P_IE_HT_OP_T) pucIE;
882 /* Workaround that some APs fill primary channel field by its
883 * secondary channel, but its DS IE is correct 20110610
884 */
885 if (ucPrimaryChannel == 0) {
886 ucPrimaryChannel = prHtOp->ucPrimaryChannel;
887 }
888 prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1;
889 prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2;
890 prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3;
891
892 if (!prBssInfo->fg40mBwAllowed) {
893 prBssInfo->ucHtOpInfo1 &=
894 ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH);
895 }
896
897 if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
898 prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)
899 (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO);
900 }
901
902 prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T)
903 (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION);
904
905 /* To do: process regulatory class 16 */
906 if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT)
907 && 0 /* && regulatory class is 16 */) {
908 prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED;
909 } else if (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) {
910 prBssInfo->eGfOperationMode = GF_MODE_PROTECT;
911 } else {
912 prBssInfo->eGfOperationMode = GF_MODE_NORMAL;
913 }
914
915 prBssInfo->eRifsOperationMode =
916 (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ?
917 RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED;
918
919 break;
920
921 case ELEM_ID_20_40_BSS_COEXISTENCE:
922 if (!RLM_NET_IS_11N(prBssInfo)) {
923 break;
924 }
925 /* To do: store if scanning exemption grant to BssInfo */
926 break;
927
928 case ELEM_ID_OBSS_SCAN_PARAMS:
929 if (!RLM_NET_IS_11N(prBssInfo) ||
930 IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) {
931 break;
932 }
933 /* Store OBSS parameters to BssInfo */
934 prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE;
935 break;
936
937 case ELEM_ID_EXTENDED_CAP:
938 if (!RLM_NET_IS_11N(prBssInfo)) {
939 break;
940 }
941 /* To do: store extended capability (PSMP, coexist) to BssInfo */
942 break;
943
944 case ELEM_ID_ERP_INFO:
945 if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) || prBssInfo->eBand != BAND_2G4) {
946 break;
947 }
948 ucERP = ERP_INFO_IE(pucIE)->ucERP;
949 prBssInfo->fgErpProtectMode =
950 (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE;
951
952 if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) {
953 prBssInfo->fgUseShortPreamble = FALSE;
954 }
955 break;
956
957 case ELEM_ID_DS_PARAM_SET:
958 if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
959 ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
960 }
961 break;
962
963 #if CFG_SUPPORT_QUIET && 0
964 /* Note: RRM code should be moved to independent RRM function by
965 * component design rule. But we attach it to RLM temporarily
966 */
967 case ELEM_ID_QUIET:
968 rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE);
969 fgHasQuietIE = TRUE;
970 break;
971 #endif
972 default:
973 break;
974 } /* end of switch */
975 } /* end of IE_FOR_EACH */
976
977 /* Some AP will have wrong channel number (255) when running time.
978 * Check if correct channel number information. 20110501
979 */
980 if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) ||
981 (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 || ucPrimaryChannel <= 14))) {
982 ucPrimaryChannel = 0;
983 }
984 #if CFG_SUPPORT_QUIET && 0
985 if (!fgHasQuietIE) {
986 rrmQuietIeNotExist(prAdapter, prBssInfo);
987 }
988 #endif
989
990 /* Check if OBSS scan process will launch */
991 if (!prAdapter->fgEnOnlineScan || !prObssScnParam ||
992 !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) ||
993 prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) {
994
995 /* Note: it is ok not to stop rObssScanTimer() here */
996 prBssInfo->u2ObssScanInterval = 0;
997 } else {
998 if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) {
999 prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL;
1000 }
1001 if (prBssInfo->u2ObssScanInterval != prObssScnParam->u2TriggerScanInterval) {
1002
1003 prBssInfo->u2ObssScanInterval = prObssScnParam->u2TriggerScanInterval;
1004
1005 /* Start timer to trigger OBSS scanning */
1006 cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
1007 prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
1008 }
1009 }
1010
1011 return ucPrimaryChannel;
1012 }
1013
1014 /*----------------------------------------------------------------------------*/
1015 /*!
1016 * \brief AIS or P2P GC.
1017 *
1018 * \param[in]
1019 *
1020 * \return none
1021 */
1022 /*----------------------------------------------------------------------------*/
1023 static BOOLEAN
1024 rlmRecBcnFromNeighborForClient(P_ADAPTER_T prAdapter,
1025 P_BSS_INFO_T prBssInfo,
1026 P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
1027 {
1028 UINT_16 u2Offset, i;
1029 UINT_8 ucPriChannel, ucSecChannel;
1030 ENUM_CHNL_EXT_T eSCO;
1031 BOOLEAN fgHtBss, fg20mReq;
1032
1033 ASSERT(prAdapter);
1034 ASSERT(prBssInfo && prSwRfb);
1035 ASSERT(pucIE);
1036
1037 /* Record it to channel list to change 20/40 bandwidth */
1038 ucPriChannel = 0;
1039 eSCO = CHNL_EXT_SCN;
1040
1041 fgHtBss = FALSE;
1042 fg20mReq = FALSE;
1043
1044 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1045 switch (IE_ID(pucIE)) {
1046 case ELEM_ID_HT_CAP:
1047 {
1048 P_IE_HT_CAP_T prHtCap;
1049
1050 if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1051 break;
1052 }
1053
1054 prHtCap = (P_IE_HT_CAP_T) pucIE;
1055 if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) {
1056 fg20mReq = TRUE;
1057 }
1058 fgHtBss = TRUE;
1059 break;
1060 }
1061 case ELEM_ID_HT_OP:
1062 {
1063 P_IE_HT_OP_T prHtOp;
1064
1065 if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1066 break;
1067 }
1068
1069 prHtOp = (P_IE_HT_OP_T) pucIE;
1070 /* Workaround that some APs fill primary channel field by its
1071 * secondary channel, but its DS IE is correct 20110610
1072 */
1073 if (ucPriChannel == 0) {
1074 ucPriChannel = prHtOp->ucPrimaryChannel;
1075 }
1076
1077 if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1078 eSCO =
1079 (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO);
1080 }
1081 break;
1082 }
1083 case ELEM_ID_20_40_BSS_COEXISTENCE:
1084 {
1085 P_IE_20_40_COEXIST_T prCoexist;
1086
1087 if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) {
1088 break;
1089 }
1090
1091 prCoexist = (P_IE_20_40_COEXIST_T) pucIE;
1092 if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) {
1093 fg20mReq = TRUE;
1094 }
1095 break;
1096 }
1097 case ELEM_ID_DS_PARAM_SET:
1098 if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) {
1099 break;
1100 }
1101 ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
1102 break;
1103
1104 default:
1105 break;
1106 }
1107 }
1108
1109
1110 /* To do: Update channel list and 5G band. All channel lists have the same
1111 * update procedure. We should give it the entry pointer of desired
1112 * channel list.
1113 */
1114 if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) {
1115 return FALSE;
1116 }
1117
1118 if (ucPriChannel == 0 || ucPriChannel > 14) {
1119 ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr);
1120 }
1121
1122 if (fgHtBss) {
1123 ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
1124 for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
1125 if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) {
1126 break;
1127 }
1128 }
1129 if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1130 prBssInfo->auc2G_PriChnlList[i] = ucPriChannel;
1131 prBssInfo->auc2G_PriChnlList[0]++;
1132 }
1133
1134 /* Update secondary channel */
1135 if (eSCO != CHNL_EXT_SCN) {
1136 ucSecChannel = (eSCO == CHNL_EXT_SCA) ?
1137 (ucPriChannel + 4) : (ucPriChannel - 4);
1138
1139 ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
1140 for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] &&
1141 i <= CHNL_LIST_SZ_2G; i++) {
1142 if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) {
1143 break;
1144 }
1145 }
1146 if ((i > prBssInfo->auc2G_SecChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1147 prBssInfo->auc2G_SecChnlList[i] = ucSecChannel;
1148 prBssInfo->auc2G_SecChnlList[0]++;
1149 }
1150 }
1151
1152 /* Update 20M bandwidth request channels */
1153 if (fg20mReq) {
1154 ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
1155 for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
1156 i <= CHNL_LIST_SZ_2G; i++) {
1157 if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) {
1158 break;
1159 }
1160 }
1161 if ((i > prBssInfo->auc2G_20mReqChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1162 prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel;
1163 prBssInfo->auc2G_20mReqChnlList[0]++;
1164 }
1165 }
1166 } else {
1167 /* Update non-HT channel list */
1168 ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
1169 for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] && i <= CHNL_LIST_SZ_2G; i++) {
1170 if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) {
1171 break;
1172 }
1173 }
1174 if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1175 prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel;
1176 prBssInfo->auc2G_NonHtChnlList[0]++;
1177 }
1178
1179 }
1180
1181 return FALSE;
1182 }
1183
1184
1185 /*----------------------------------------------------------------------------*/
1186 /*!
1187 * \brief AIS or P2P GC.
1188 *
1189 * \param[in]
1190 *
1191 * \return none
1192 */
1193 /*----------------------------------------------------------------------------*/
1194 static BOOLEAN
1195 rlmRecBcnInfoForClient(P_ADAPTER_T prAdapter,
1196 P_BSS_INFO_T prBssInfo,
1197 P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
1198 {
1199 ASSERT(prAdapter);
1200 ASSERT(prBssInfo && prSwRfb);
1201 ASSERT(pucIE);
1202
1203 #if 0 /* SW migration 2010/8/20 */
1204 /* Note: we shall not update parameters when scanning, otherwise
1205 * channel and bandwidth will not be correct or asserted failure
1206 * during scanning.
1207 * Note: remove channel checking. All received Beacons should be processed
1208 * if measurement or other actions are executed in adjacent channels
1209 * and Beacon content checking mechanism is not disabled.
1210 */
1211 if (IS_SCAN_ACTIVE()
1212 /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */
1213 ) {
1214 return FALSE;
1215 }
1216 #endif
1217
1218 /* Handle change of slot time */
1219 prBssInfo->u2CapInfo = ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->u2CapInfo;
1220 prBssInfo->fgUseShortSlotTime =
1221 (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1222
1223 rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength);
1224
1225 return TRUE;
1226 }
1227
1228 /*----------------------------------------------------------------------------*/
1229 /*!
1230 * \brief
1231 *
1232 * \param[in]
1233 *
1234 * \return none
1235 */
1236 /*----------------------------------------------------------------------------*/
1237 VOID rlmProcessBcn(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
1238 {
1239 P_BSS_INFO_T prBssInfo;
1240 BOOLEAN fgNewParameter;
1241 UINT_8 ucNetIdx;
1242
1243 ASSERT(prAdapter);
1244 ASSERT(prSwRfb);
1245 ASSERT(pucIE);
1246
1247 fgNewParameter = FALSE;
1248
1249 /* When concurrent networks exist, GO shall have the same handle as
1250 * the other BSS, so the Beacon shall be procesed for bandwidth and
1251 * protection mechanism.
1252 * Note1: we do not have 2 AP (GO) cases simultaneously now.
1253 * Note2: If we are GO, concurrent AIS AP should detect it and reflect
1254 * action in its Beacon, so AIS STA just follows Beacon from AP.
1255 */
1256 RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) {
1257 prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
1258 ASSERT(prBssInfo);
1259
1260 if (IS_BSS_ACTIVE(prBssInfo)) {
1261 if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
1262 prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
1263 /* P2P client or AIS infra STA */
1264 if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID, ((P_WLAN_MAC_MGMT_HEADER_T)
1265 (prSwRfb->pvHeader))->
1266 aucBSSID)) {
1267
1268 fgNewParameter = rlmRecBcnInfoForClient(prAdapter,
1269 prBssInfo, prSwRfb,
1270 pucIE, u2IELength);
1271 } else {
1272 fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter,
1273 prBssInfo,
1274 prSwRfb,
1275 pucIE,
1276 u2IELength);
1277 }
1278 }
1279 #if CFG_ENABLE_WIFI_DIRECT
1280 else if (prAdapter->fgIsP2PRegistered &&
1281 (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT ||
1282 prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) {
1283 /* AP scan to check if 20/40M bandwidth is permitted */
1284 rlmRecBcnFromNeighborForClient(prAdapter,
1285 prBssInfo, prSwRfb, pucIE,
1286 u2IELength);
1287 }
1288 #endif
1289 else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
1290 /* To do: Ad-hoc */
1291 }
1292
1293 /* Appy new parameters if necessary */
1294 if (fgNewParameter) {
1295 rlmSyncOperationParams(prAdapter, prBssInfo);
1296 fgNewParameter = FALSE;
1297 }
1298 } /* end of IS_BSS_ACTIVE() */
1299 } /* end of RLM_NET_FOR_EACH_NO_BOW */
1300 }
1301
1302 /*----------------------------------------------------------------------------*/
1303 /*!
1304 * \brief This function should be invoked after judging successful association.
1305 *
1306 * \param[in]
1307 *
1308 * \return none
1309 */
1310 /*----------------------------------------------------------------------------*/
1311 VOID
1312 rlmProcessAssocRsp(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
1313 {
1314 P_BSS_INFO_T prBssInfo;
1315 P_STA_RECORD_T prStaRec;
1316 UINT_8 ucPriChannel;
1317
1318 ASSERT(prAdapter);
1319 ASSERT(prSwRfb);
1320 ASSERT(pucIE);
1321
1322 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1323 ASSERT(prStaRec);
1324 if (!prStaRec) {
1325 return;
1326 }
1327 ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1328
1329 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1330 ASSERT(prStaRec == prBssInfo->prStaRecOfAP);
1331
1332 /* To do: the invoked function is used to clear all members. It may be
1333 * done by center mechanism in invoker.
1334 */
1335 rlmBssReset(prAdapter, prBssInfo);
1336
1337 prBssInfo->fgUseShortSlotTime =
1338 (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1339
1340 if ((ucPriChannel = rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength)) > 0) {
1341 prBssInfo->ucPrimaryChannel = ucPriChannel;
1342 }
1343
1344 if (!RLM_NET_IS_11N(prBssInfo) || !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
1345 prBssInfo->fg40mBwAllowed = FALSE;
1346 }
1347
1348 /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which
1349 * shall be invoked afterwards.
1350 * Update channel, bandwidth and protection mode by nicUpdateBss()
1351 */
1352 #if 1
1353 if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
1354
1355 DBGLOG(AIS, WARN, ("Force P2P BW to 20\n"));
1356 prBssInfo->fgAssoc40mBwAllowed = FALSE;
1357 }
1358 #endif
1359
1360
1361 }
1362
1363 /*----------------------------------------------------------------------------*/
1364 /*!
1365 * \brief This function should be invoked after judging successful association.
1366 *
1367 * \param[in]
1368 *
1369 * \return none
1370 */
1371 /*----------------------------------------------------------------------------*/
1372 VOID rlmFillSyncCmdParam(P_CMD_SET_BSS_RLM_PARAM_T prCmdBody, P_BSS_INFO_T prBssInfo)
1373 {
1374 ASSERT(prCmdBody && prBssInfo);
1375 if (!prCmdBody || !prBssInfo) {
1376 return;
1377 }
1378
1379 prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
1380 prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand;
1381 prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
1382 prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO;
1383 prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode;
1384 prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode;
1385 prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode;
1386 prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode;
1387 prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3;
1388 prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2;
1389 prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1;
1390 prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble;
1391 prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime;
1392 prCmdBody->ucCheckId = 0x72;
1393
1394 if (RLM_NET_PARAM_VALID(prBssInfo)) {
1395 DBGLOG(RLM, INFO, ("N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n",
1396 prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand,
1397 prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco,
1398 prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode,
1399 prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime,
1400 prCmdBody->ucUseShortPreamble));
1401 } else {
1402 DBGLOG(RLM, INFO, ("N=%d closed\n", prCmdBody->ucNetTypeIndex));
1403 }
1404 }
1405
1406 /*----------------------------------------------------------------------------*/
1407 /*!
1408 * \brief This function will operation parameters based on situations of
1409 * concurrent networks. Channel, bandwidth, protection mode, supported
1410 * rate will be modified.
1411 *
1412 * \param[in]
1413 *
1414 * \return none
1415 */
1416 /*----------------------------------------------------------------------------*/
1417 VOID rlmSyncOperationParams(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
1418 {
1419 P_CMD_SET_BSS_RLM_PARAM_T prCmdBody;
1420 WLAN_STATUS rStatus;
1421
1422 ASSERT(prAdapter);
1423 ASSERT(prBssInfo);
1424
1425 prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T)
1426 cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T));
1427 ASSERT(prCmdBody);
1428
1429 /* To do: exception handle */
1430 if (!prCmdBody) {
1431 DBGLOG(RLM, WARN, ("No buf for sync RLM params (Net=%d)\n",
1432 prBssInfo->ucNetTypeIndex));
1433 return;
1434 }
1435
1436 rlmFillSyncCmdParam(prCmdBody, prBssInfo);
1437
1438 rStatus = wlanSendSetQueryCmd(prAdapter, /* prAdapter */
1439 CMD_ID_SET_BSS_RLM_PARAM, /* ucCID */
1440 TRUE, /* fgSetQuery */
1441 FALSE, /* fgNeedResp */
1442 FALSE, /* fgIsOid */
1443 NULL, /* pfCmdDoneHandler */
1444 NULL, /* pfCmdTimeoutHandler */
1445 sizeof(CMD_SET_BSS_RLM_PARAM_T), /* u4SetQueryInfoLen */
1446 (PUINT_8) prCmdBody, /* pucInfoBuffer */
1447 NULL, /* pvSetQueryBuffer */
1448 0 /* u4SetQueryBufferLen */
1449 );
1450
1451 ASSERT(rStatus == WLAN_STATUS_PENDING);
1452
1453 cnmMemFree(prAdapter, prCmdBody);
1454 }
1455
1456 #if CFG_SUPPORT_AAA
1457 /*----------------------------------------------------------------------------*/
1458 /*!
1459 * \brief This function should be invoked after judging successful association.
1460 *
1461 * \param[in]
1462 *
1463 * \return none
1464 */
1465 /*----------------------------------------------------------------------------*/
1466 VOID
1467 rlmProcessAssocReq(P_ADAPTER_T prAdapter, P_SW_RFB_T prSwRfb, PUINT_8 pucIE, UINT_16 u2IELength)
1468 {
1469 P_BSS_INFO_T prBssInfo;
1470 P_STA_RECORD_T prStaRec;
1471 UINT_16 u2Offset;
1472 P_IE_HT_CAP_T prHtCap;
1473
1474 ASSERT(prAdapter);
1475 ASSERT(prSwRfb);
1476 ASSERT(pucIE);
1477
1478 prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1479 ASSERT(prStaRec);
1480 if (!prStaRec) {
1481 return;
1482 }
1483 ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1484
1485 prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1486
1487 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1488 switch (IE_ID(pucIE)) {
1489 case ELEM_ID_HT_CAP:
1490 if (!RLM_NET_IS_11N(prBssInfo) ||
1491 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1492 break;
1493 }
1494 prHtCap = (P_IE_HT_CAP_T) pucIE;
1495 prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
1496 prStaRec->fgSupMcs32 =
1497 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32 / 8] & BIT(0)) ? TRUE : FALSE;
1498
1499 prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
1500 prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
1501 prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
1502 prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
1503 prStaRec->ucAselCap = prHtCap->ucAselCap;
1504 break;
1505
1506 default:
1507 break;
1508 } /* end of switch */
1509 } /* end of IE_FOR_EACH */
1510 }
1511 #endif /* CFG_SUPPORT_AAA */
1512
1513 /*----------------------------------------------------------------------------*/
1514 /*!
1515 * \brief It is for both STA and AP modes
1516 *
1517 * \param[in]
1518 *
1519 * \return none
1520 */
1521 /*----------------------------------------------------------------------------*/
1522 VOID rlmBssInitForAPandIbss(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
1523 {
1524 ASSERT(prAdapter);
1525 ASSERT(prBssInfo);
1526
1527 #if CFG_ENABLE_WIFI_DIRECT
1528 if (prAdapter->fgIsP2PRegistered && prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1529
1530 rlmBssInitForAP(prAdapter, prBssInfo);
1531 }
1532 #endif
1533 }
1534
1535 /*----------------------------------------------------------------------------*/
1536 /*!
1537 * \brief It is for both STA and AP modes
1538 *
1539 * \param[in]
1540 *
1541 * \return none
1542 */
1543 /*----------------------------------------------------------------------------*/
1544 VOID rlmBssAborted(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
1545 {
1546 ASSERT(prAdapter);
1547 ASSERT(prBssInfo);
1548
1549 rlmBssReset(prAdapter, prBssInfo);
1550
1551 prBssInfo->fg40mBwAllowed = FALSE;
1552 prBssInfo->fgAssoc40mBwAllowed = FALSE;
1553
1554 /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so
1555 * the sync CMD is not needed here.
1556 */
1557 }
1558
1559 /*----------------------------------------------------------------------------*/
1560 /*!
1561 * \brief All RLM timers will also be stopped.
1562 *
1563 * \param[in]
1564 *
1565 * \return none
1566 */
1567 /*----------------------------------------------------------------------------*/
1568 static VOID rlmBssReset(P_ADAPTER_T prAdapter, P_BSS_INFO_T prBssInfo)
1569 {
1570 ASSERT(prAdapter);
1571 ASSERT(prBssInfo);
1572
1573 /* HT related parameters */
1574 prBssInfo->ucHtOpInfo1 = 0; /* RIFS disabled. 20MHz */
1575 prBssInfo->u2HtOpInfo2 = 0;
1576 prBssInfo->u2HtOpInfo3 = 0;
1577
1578 prBssInfo->eBssSCO = 0;
1579 prBssInfo->fgErpProtectMode = 0;
1580 prBssInfo->eHtProtectMode = 0;
1581 prBssInfo->eGfOperationMode = 0;
1582 prBssInfo->eRifsOperationMode = 0;
1583
1584 /* OBSS related parameters */
1585 prBssInfo->auc2G_20mReqChnlList[0] = 0;
1586 prBssInfo->auc2G_NonHtChnlList[0] = 0;
1587 prBssInfo->auc2G_PriChnlList[0] = 0;
1588 prBssInfo->auc2G_SecChnlList[0] = 0;
1589 prBssInfo->auc5G_20mReqChnlList[0] = 0;
1590 prBssInfo->auc5G_NonHtChnlList[0] = 0;
1591 prBssInfo->auc5G_PriChnlList[0] = 0;
1592 prBssInfo->auc5G_SecChnlList[0] = 0;
1593
1594 /* All RLM timers will also be stopped */
1595 cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer);
1596 prBssInfo->u2ObssScanInterval = 0;
1597
1598 prBssInfo->fgObssErpProtectMode = 0; /* GO only */
1599 prBssInfo->eObssHtProtectMode = 0; /* GO only */
1600 prBssInfo->eObssGfOperationMode = 0; /* GO only */
1601 prBssInfo->fgObssRifsOperationMode = 0; /* GO only */
1602 prBssInfo->fgObssActionForcedTo20M = 0; /* GO only */
1603 prBssInfo->fgObssBeaconForcedTo20M = 0; /* GO only */
1604 }