wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931 / 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
353 rlmFillHtCapIE (
354     P_ADAPTER_T     prAdapter,
355     P_BSS_INFO_T    prBssInfo,
356     P_MSDU_INFO_T   prMsduInfo
357     );
358
359 static VOID
360 rlmFillExtCapIE (
361     P_ADAPTER_T     prAdapter,
362     P_BSS_INFO_T    prBssInfo,
363     P_MSDU_INFO_T   prMsduInfo
364     );
365
366 static VOID
367 rlmFillHtOpIE (
368     P_ADAPTER_T         prAdapter,
369     P_BSS_INFO_T        prBssInfo,
370     P_MSDU_INFO_T       prMsduInfo
371     );
372
373 static UINT_8
374 rlmRecIeInfoForClient (
375     P_ADAPTER_T         prAdapter,
376     P_BSS_INFO_T        prBssInfo,
377     PUINT_8             pucIE,
378     UINT_16             u2IELength
379     );
380
381 static BOOLEAN
382 rlmRecBcnFromNeighborForClient (
383     P_ADAPTER_T         prAdapter,
384     P_BSS_INFO_T        prBssInfo,
385     P_SW_RFB_T          prSwRfb,
386     PUINT_8             pucIE,
387     UINT_16             u2IELength
388     );
389
390 static BOOLEAN
391 rlmRecBcnInfoForClient (
392     P_ADAPTER_T         prAdapter,
393     P_BSS_INFO_T        prBssInfo,
394     P_SW_RFB_T          prSwRfb,
395     PUINT_8             pucIE,
396     UINT_16             u2IELength
397     );
398
399 static VOID
400 rlmBssReset (
401     P_ADAPTER_T         prAdapter,
402     P_BSS_INFO_T        prBssInfo
403     );
404
405 /*******************************************************************************
406 *                              F U N C T I O N S
407 ********************************************************************************
408 */
409
410 /*----------------------------------------------------------------------------*/
411 /*!
412 * \brief
413 *
414 * \param[in]
415 *
416 * \return none
417 */
418 /*----------------------------------------------------------------------------*/
419 VOID
420 rlmFsmEventInit (
421     P_ADAPTER_T     prAdapter
422     )
423 {
424     ASSERT(prAdapter);
425
426     /* Note: assume TIMER_T structures are reset to zero or stopped
427      * before invoking this function.
428      */
429
430     /* Initialize OBSS FSM */
431     rlmObssInit(prAdapter);
432 }
433
434 /*----------------------------------------------------------------------------*/
435 /*!
436 * \brief
437 *
438 * \param[in]
439 *
440 * \return none
441 */
442 /*----------------------------------------------------------------------------*/
443 VOID
444 rlmFsmEventUninit (
445     P_ADAPTER_T     prAdapter
446     )
447 {
448     P_BSS_INFO_T    prBssInfo;
449     UINT_8          ucNetIdx;
450
451     ASSERT(prAdapter);
452
453     RLM_NET_FOR_EACH(ucNetIdx) {
454         prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
455         ASSERT(prBssInfo);
456
457         /* Note: all RLM timers will also be stopped.
458          *       Now only one OBSS scan timer.
459          */
460         rlmBssReset(prAdapter, prBssInfo);
461     }
462 }
463
464 /*----------------------------------------------------------------------------*/
465 /*!
466 * \brief For probe request, association request
467 *
468 * \param[in]
469 *
470 * \return none
471 */
472 /*----------------------------------------------------------------------------*/
473 VOID
474 rlmReqGenerateHtCapIE (
475     P_ADAPTER_T     prAdapter,
476     P_MSDU_INFO_T   prMsduInfo
477     )
478 {
479     P_BSS_INFO_T    prBssInfo;
480     P_STA_RECORD_T  prStaRec;
481
482     ASSERT(prAdapter);
483     ASSERT(prMsduInfo);
484
485     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
486     ASSERT(prBssInfo);
487
488     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
489
490     if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
491         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
492
493         rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
494     }
495 }
496
497 /*----------------------------------------------------------------------------*/
498 /*!
499 * \brief For probe request, association request
500 *
501 * \param[in]
502 *
503 * \return none
504 */
505 /*----------------------------------------------------------------------------*/
506 VOID
507 rlmReqGenerateExtCapIE (
508     P_ADAPTER_T     prAdapter,
509     P_MSDU_INFO_T   prMsduInfo
510     )
511 {
512     P_BSS_INFO_T    prBssInfo;
513     P_STA_RECORD_T  prStaRec;
514
515     ASSERT(prAdapter);
516     ASSERT(prMsduInfo);
517
518     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
519     ASSERT(prBssInfo);
520
521     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
522
523     if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) &&
524         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
525
526         rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
527     }
528 }
529
530 /*----------------------------------------------------------------------------*/
531 /*!
532 * \brief For probe response (GO, IBSS) and association response
533 *
534 * \param[in]
535 *
536 * \return none
537 */
538 /*----------------------------------------------------------------------------*/
539 VOID
540 rlmRspGenerateHtCapIE (
541     P_ADAPTER_T     prAdapter,
542     P_MSDU_INFO_T   prMsduInfo
543     )
544 {
545     P_BSS_INFO_T    prBssInfo;
546     P_STA_RECORD_T  prStaRec;
547
548     ASSERT(prAdapter);
549     ASSERT(prMsduInfo);
550     ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
551
552     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
553     ASSERT(prBssInfo);
554
555     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
556
557     if (RLM_NET_IS_11N(prBssInfo) &&
558         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
559
560         rlmFillHtCapIE(prAdapter, prBssInfo, prMsduInfo);
561     }
562 }
563
564 /*----------------------------------------------------------------------------*/
565 /*!
566 * \brief For probe response (GO, IBSS) and association response
567 *
568 * \param[in]
569 *
570 * \return none
571 */
572 /*----------------------------------------------------------------------------*/
573 VOID
574 rlmRspGenerateExtCapIE (
575     P_ADAPTER_T     prAdapter,
576     P_MSDU_INFO_T   prMsduInfo
577     )
578 {
579     P_BSS_INFO_T    prBssInfo;
580     P_STA_RECORD_T  prStaRec;
581
582     ASSERT(prAdapter);
583     ASSERT(prMsduInfo);
584     ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
585
586     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
587     ASSERT(prBssInfo);
588
589     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
590
591     if (RLM_NET_IS_11N(prBssInfo) &&
592         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
593
594         rlmFillExtCapIE(prAdapter, prBssInfo, prMsduInfo);
595     }
596 }
597
598 /*----------------------------------------------------------------------------*/
599 /*!
600 * \brief For probe response (GO, IBSS) and association response
601 *
602 * \param[in]
603 *
604 * \return none
605 */
606 /*----------------------------------------------------------------------------*/
607 VOID
608 rlmRspGenerateHtOpIE (
609     P_ADAPTER_T     prAdapter,
610     P_MSDU_INFO_T   prMsduInfo
611     )
612 {
613     P_BSS_INFO_T    prBssInfo;
614     P_STA_RECORD_T  prStaRec;
615
616     ASSERT(prAdapter);
617     ASSERT(prMsduInfo);
618     ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
619
620     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
621
622     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
623     ASSERT(prBssInfo);
624
625     if (RLM_NET_IS_11N(prBssInfo) &&
626         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N))) {
627
628         rlmFillHtOpIE(prAdapter, prBssInfo, prMsduInfo);
629     }
630 }
631
632 /*----------------------------------------------------------------------------*/
633 /*!
634 * \brief For probe response (GO, IBSS) and association response
635 *
636 * \param[in]
637 *
638 * \return none
639 */
640 /*----------------------------------------------------------------------------*/
641 VOID
642 rlmRspGenerateErpIE (
643     P_ADAPTER_T     prAdapter,
644     P_MSDU_INFO_T   prMsduInfo
645     )
646 {
647     P_BSS_INFO_T    prBssInfo;
648     P_STA_RECORD_T  prStaRec;
649     P_IE_ERP_T      prErpIe;
650
651     ASSERT(prAdapter);
652     ASSERT(prMsduInfo);
653     ASSERT(IS_NET_ACTIVE(prAdapter, prMsduInfo->ucNetworkType));
654
655     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
656
657     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prMsduInfo->ucNetworkType];
658     ASSERT(prBssInfo);
659
660     if (RLM_NET_IS_11GN(prBssInfo) && prBssInfo->eBand == BAND_2G4 &&
661         (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11GN))) {
662         prErpIe = (P_IE_ERP_T)
663                 (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
664
665         /* Add ERP IE */
666         prErpIe->ucId = ELEM_ID_ERP_INFO;
667         prErpIe->ucLength = 1;
668
669         prErpIe->ucERP = prBssInfo->fgObssErpProtectMode ?
670             ERP_INFO_USE_PROTECTION : 0;
671
672         if (prBssInfo->fgErpProtectMode) {
673             prErpIe->ucERP |=
674                 (ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION);
675         }
676
677         /* Handle barker preamble */
678         if (!prBssInfo->fgUseShortPreamble) {
679             prErpIe->ucERP |= ERP_INFO_BARKER_PREAMBLE_MODE;
680         }
681
682         ASSERT(IE_SIZE(prErpIe) <= (ELEM_HDR_LEN+ ELEM_MAX_LEN_ERP));
683
684         prMsduInfo->u2FrameLength += IE_SIZE(prErpIe);
685     }
686 }
687
688 /*----------------------------------------------------------------------------*/
689 /*!
690 * \brief
691 *
692 * \param[in]
693 *
694 * \return none
695 */
696 /*----------------------------------------------------------------------------*/
697 static VOID
698 rlmFillHtCapIE (
699     P_ADAPTER_T     prAdapter,
700     P_BSS_INFO_T    prBssInfo,
701     P_MSDU_INFO_T   prMsduInfo
702     )
703 {
704     P_IE_HT_CAP_T           prHtCap;
705     P_SUP_MCS_SET_FIELD     prSupMcsSet;
706     BOOLEAN                 fg40mAllowed;
707
708     ASSERT(prAdapter);
709     ASSERT(prBssInfo);
710     ASSERT(prMsduInfo);
711
712     fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
713
714     prHtCap = (P_IE_HT_CAP_T)
715               (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
716
717     /* Add HT capabilities IE */
718     prHtCap->ucId = ELEM_ID_HT_CAP;
719     prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN;
720
721     prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL;
722     if (!fg40mAllowed) {
723         prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH |
724             HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M);
725     }
726     if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) {
727         prHtCap->u2HtCapInfo &=
728             ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
729     }
730
731     prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL;
732
733     prSupMcsSet = &prHtCap->rSupMcsSet;
734     kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0],
735                 SUP_MCS_RX_BITMASK_OCTET_NUM);
736
737     prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7);
738
739     if (fg40mAllowed) {
740         prSupMcsSet->aucRxMcsBitmask[32/8] = BIT(0); /* MCS32 */
741     }
742     prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE;
743     prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL;
744
745     prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL;
746     if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
747         prHtCap->u2HtExtendedCap &=
748             ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE);
749     }
750
751     prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL;
752
753     prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL;
754
755
756     ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP));
757
758     prMsduInfo->u2FrameLength += IE_SIZE(prHtCap);
759 }
760
761 /*----------------------------------------------------------------------------*/
762 /*!
763 * \brief
764 *
765 * \param[in]
766 *
767 * \return none
768 */
769 /*----------------------------------------------------------------------------*/
770 static VOID
771 rlmFillExtCapIE (
772     P_ADAPTER_T     prAdapter,
773     P_BSS_INFO_T    prBssInfo,
774     P_MSDU_INFO_T   prMsduInfo
775     )
776 {
777     P_EXT_CAP_T     prExtCap;
778     BOOLEAN         fg40mAllowed;
779
780     ASSERT(prAdapter);
781     ASSERT(prMsduInfo);
782
783     fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
784
785     /* Add Extended Capabilities IE */
786     prExtCap = (P_EXT_CAP_T)
787                (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
788
789     prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
790     prExtCap->ucLength = 1;
791     prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
792
793     if (!fg40mAllowed) {
794         prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT;
795     }
796
797     if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
798         prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
799     }
800
801     ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
802
803     prMsduInfo->u2FrameLength += IE_SIZE(prExtCap);
804 }
805
806 /*----------------------------------------------------------------------------*/
807 /*!
808 * \brief
809 *
810 * \param[in]
811 *
812 * \return none
813 */
814 /*----------------------------------------------------------------------------*/
815 static VOID
816 rlmFillHtOpIE (
817     P_ADAPTER_T     prAdapter,
818     P_BSS_INFO_T    prBssInfo,
819     P_MSDU_INFO_T   prMsduInfo
820     )
821 {
822     P_IE_HT_OP_T        prHtOp;
823     UINT_16             i;
824
825     ASSERT(prAdapter);
826     ASSERT(prBssInfo);
827     ASSERT(prMsduInfo);
828
829     prHtOp = (P_IE_HT_OP_T)
830              (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
831
832     /* Add HT operation IE */
833     prHtOp->ucId = ELEM_ID_HT_OP;
834     prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN;
835
836     /* RIFS and 20/40 bandwidth operations are included */
837     prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
838     prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1;
839
840     /* Decide HT protection mode field */
841     if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) {
842         prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT;
843     }
844     else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
845         prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER;
846     }
847     else {
848         /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */
849         prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode;
850     }
851
852     if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) {
853         /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED
854          * Note: it will also be set in ad-hoc network
855          */
856         prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
857     }
858
859     if (0 /* Regulatory class 16 */ &&
860         prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
861         /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection
862          * although it is possible to have no protection by spec.
863          */
864         prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
865     }
866
867     prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3;   /* To do: handle L-SIG TXOP */
868
869     /* No basic MCSx are needed temporarily */
870     for (i = 0; i < 16; i++) {
871         prHtOp->aucBasicMcsSet[i] = 0;
872     }
873
874     ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP));
875
876     prMsduInfo->u2FrameLength += IE_SIZE(prHtOp);
877 }
878
879 /*----------------------------------------------------------------------------*/
880 /*!
881 * \brief This function should be invoked to update parameters of associated AP.
882 *        (Association response and Beacon)
883 *
884 * \param[in]
885 *
886 * \return none
887 */
888 /*----------------------------------------------------------------------------*/
889 static UINT_8
890 rlmRecIeInfoForClient (
891     P_ADAPTER_T         prAdapter,
892     P_BSS_INFO_T        prBssInfo,
893     PUINT_8             pucIE,
894     UINT_16             u2IELength
895     )
896 {
897     UINT_16                 u2Offset;
898     P_STA_RECORD_T          prStaRec;
899     P_IE_HT_CAP_T           prHtCap;
900     P_IE_HT_OP_T            prHtOp;
901     P_IE_OBSS_SCAN_PARAM_T  prObssScnParam;
902     UINT_8                  ucERP, ucPrimaryChannel;
903 #if CFG_SUPPORT_QUIET && 0
904     BOOLEAN                 fgHasQuietIE = FALSE;
905 #endif
906
907     ASSERT(prAdapter);
908     ASSERT(prBssInfo);
909     ASSERT(pucIE);
910
911     prStaRec = prBssInfo->prStaRecOfAP;
912     ASSERT(prStaRec);
913     if (!prStaRec) {
914         return 0;
915     }
916
917     prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
918     ucPrimaryChannel = 0;
919     prObssScnParam = NULL;
920
921     /* Note: HT-related members in staRec may not be zero before, so
922      *       if following IE does not exist, they are still not zero.
923      *       These HT-related parameters are vaild only when the corresponding
924      *       BssInfo supports 802.11n, i.e., RLM_NET_IS_11N()
925      */
926     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
927         switch (IE_ID(pucIE)) {
928         case ELEM_ID_HT_CAP:
929             if (!RLM_NET_IS_11N(prBssInfo) ||
930                 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
931                 break;
932             }
933             prHtCap = (P_IE_HT_CAP_T) pucIE;
934             prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
935             prStaRec->fgSupMcs32 =
936                 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32/8] & BIT(0)) ?
937                 TRUE : FALSE;
938
939             prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
940             prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
941             prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
942             prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
943             prStaRec->ucAselCap = prHtCap->ucAselCap;
944             break;
945
946         case ELEM_ID_HT_OP:
947             if (!RLM_NET_IS_11N(prBssInfo) ||
948                 IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
949                 break;
950             }
951             prHtOp = (P_IE_HT_OP_T) pucIE;
952             /* Workaround that some APs fill primary channel field by its
953              * secondary channel, but its DS IE is correct 20110610
954              */
955             if (ucPrimaryChannel == 0) {
956                 ucPrimaryChannel = prHtOp->ucPrimaryChannel;
957             }
958             prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1;
959             prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2;
960             prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3;
961
962             if (!prBssInfo->fg40mBwAllowed) {
963                 prBssInfo->ucHtOpInfo1 &=
964                     ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH);
965             }
966
967             if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
968                 prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)
969                         (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO);
970             }
971
972             prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T)
973                 (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION);
974
975             /* To do: process regulatory class 16 */
976             if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT)
977                 && 0 /* && regulatory class is 16 */) {
978                 prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED;
979             }
980             else if (prBssInfo->u2HtOpInfo2&HT_OP_INFO2_NON_GF_HT_STA_PRESENT) {
981                 prBssInfo->eGfOperationMode = GF_MODE_PROTECT;
982             }
983             else {
984                 prBssInfo->eGfOperationMode = GF_MODE_NORMAL;
985             }
986
987             prBssInfo->eRifsOperationMode =
988                 (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ?
989                 RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED;
990
991             break;
992
993         case ELEM_ID_20_40_BSS_COEXISTENCE:
994             if (!RLM_NET_IS_11N(prBssInfo)) {
995                 break;
996             }
997             /* To do: store if scanning exemption grant to BssInfo */
998             break;
999
1000         case ELEM_ID_OBSS_SCAN_PARAMS:
1001             if (!RLM_NET_IS_11N(prBssInfo) ||
1002                 IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) {
1003                 break;
1004             }
1005             /* Store OBSS parameters to BssInfo */
1006             prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE;
1007             break;
1008
1009         case ELEM_ID_EXTENDED_CAP:
1010             if (!RLM_NET_IS_11N(prBssInfo)) {
1011                 break;
1012             }
1013             /* To do: store extended capability (PSMP, coexist) to BssInfo */
1014             break;
1015
1016         case ELEM_ID_ERP_INFO:
1017             if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) ||
1018                 prBssInfo->eBand != BAND_2G4) {
1019                 break;
1020             }
1021             ucERP = ERP_INFO_IE(pucIE)->ucERP;
1022             prBssInfo->fgErpProtectMode =
1023                     (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE;
1024
1025             if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) {
1026                 prBssInfo->fgUseShortPreamble = FALSE;
1027             }
1028             break;
1029
1030         case ELEM_ID_DS_PARAM_SET:
1031             if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1032                 ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
1033             }
1034             break;
1035
1036     #if CFG_SUPPORT_QUIET && 0
1037         /* Note: RRM code should be moved to independent RRM function by
1038          *       component design rule. But we attach it to RLM temporarily
1039          */
1040         case ELEM_ID_QUIET:
1041             rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE);
1042             fgHasQuietIE = TRUE;
1043             break;
1044     #endif
1045         default:
1046             break;
1047         } /* end of switch */
1048     } /* end of IE_FOR_EACH */
1049
1050     /* Some AP will have wrong channel number (255) when running time.
1051      * Check if correct channel number information. 20110501
1052      */
1053     if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) ||
1054         (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 ||
1055          ucPrimaryChannel <= 14))) {
1056         ucPrimaryChannel = 0;
1057     }
1058
1059 #if CFG_SUPPORT_QUIET && 0
1060     if (!fgHasQuietIE) {
1061         rrmQuietIeNotExist(prAdapter, prBssInfo);
1062     }
1063 #endif
1064
1065     /* Check if OBSS scan process will launch */
1066     if (!prAdapter->fgEnOnlineScan || !prObssScnParam ||
1067         !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) ||
1068         prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) {
1069
1070         /* Note: it is ok not to stop rObssScanTimer() here */
1071         prBssInfo->u2ObssScanInterval = 0;
1072     }
1073     else {
1074         if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) {
1075             prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL;
1076         }
1077         if (prBssInfo->u2ObssScanInterval !=
1078             prObssScnParam->u2TriggerScanInterval) {
1079
1080             prBssInfo->u2ObssScanInterval =
1081                 prObssScnParam->u2TriggerScanInterval;
1082
1083             /* Start timer to trigger OBSS scanning */
1084             cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
1085                 prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
1086         }
1087     }
1088
1089     return ucPrimaryChannel;
1090 }
1091
1092 /*----------------------------------------------------------------------------*/
1093 /*!
1094 * \brief AIS or P2P GC.
1095 *
1096 * \param[in]
1097 *
1098 * \return none
1099 */
1100 /*----------------------------------------------------------------------------*/
1101 static BOOLEAN
1102 rlmRecBcnFromNeighborForClient (
1103     P_ADAPTER_T         prAdapter,
1104     P_BSS_INFO_T        prBssInfo,
1105     P_SW_RFB_T          prSwRfb,
1106     PUINT_8             pucIE,
1107     UINT_16             u2IELength
1108     )
1109 {
1110     UINT_16             u2Offset, i;
1111     UINT_8              ucPriChannel, ucSecChannel;
1112     ENUM_CHNL_EXT_T     eSCO;
1113     BOOLEAN             fgHtBss, fg20mReq;
1114
1115     ASSERT(prAdapter);
1116     ASSERT(prBssInfo && prSwRfb);
1117     ASSERT(pucIE);
1118
1119     /* Record it to channel list to change 20/40 bandwidth */
1120     ucPriChannel = 0;
1121     eSCO = CHNL_EXT_SCN;
1122
1123     fgHtBss = FALSE;
1124     fg20mReq = FALSE;
1125
1126     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1127         switch (IE_ID(pucIE)) {
1128         case ELEM_ID_HT_CAP:
1129         {
1130             P_IE_HT_CAP_T           prHtCap;
1131
1132             if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1133                 break;
1134             }
1135
1136             prHtCap = (P_IE_HT_CAP_T) pucIE;
1137             if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) {
1138                 fg20mReq = TRUE;
1139             }
1140             fgHtBss = TRUE;
1141             break;
1142         }
1143         case ELEM_ID_HT_OP:
1144         {
1145             P_IE_HT_OP_T        prHtOp;
1146
1147             if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1148                 break;
1149             }
1150
1151             prHtOp = (P_IE_HT_OP_T) pucIE;
1152             /* Workaround that some APs fill primary channel field by its
1153              * secondary channel, but its DS IE is correct 20110610
1154              */
1155             if (ucPriChannel == 0) {
1156                 ucPriChannel = prHtOp->ucPrimaryChannel;
1157             }
1158
1159             if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1160                 eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO);
1161             }
1162             break;
1163         }
1164         case ELEM_ID_20_40_BSS_COEXISTENCE:
1165         {
1166             P_IE_20_40_COEXIST_T    prCoexist;
1167
1168             if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) {
1169                 break;
1170             }
1171
1172             prCoexist = (P_IE_20_40_COEXIST_T) pucIE;
1173             if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) {
1174                 fg20mReq = TRUE;
1175             }
1176             break;
1177         }
1178         case ELEM_ID_DS_PARAM_SET:
1179             if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) {
1180                 break;
1181             }
1182             ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
1183             break;
1184
1185         default:
1186             break;
1187         }
1188     }
1189
1190
1191     /* To do: Update channel list and 5G band. All channel lists have the same
1192      * update procedure. We should give it the entry pointer of desired
1193      * channel list.
1194      */
1195     if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) {
1196         return FALSE;
1197     }
1198
1199     if (ucPriChannel == 0 || ucPriChannel > 14) {
1200         ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr);
1201     }
1202
1203     if (fgHtBss) {
1204         ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
1205         for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] &&
1206              i <= CHNL_LIST_SZ_2G; i++) {
1207             if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) {
1208                 break;
1209             }
1210         }
1211         if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1212             prBssInfo->auc2G_PriChnlList[i] = ucPriChannel;
1213             prBssInfo->auc2G_PriChnlList[0]++;
1214         }
1215
1216         /* Update secondary channel */
1217         if (eSCO != CHNL_EXT_SCN) {
1218             ucSecChannel = (eSCO == CHNL_EXT_SCA) ?
1219                 (ucPriChannel + 4) : (ucPriChannel - 4);
1220
1221             ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
1222             for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] &&
1223                  i <= CHNL_LIST_SZ_2G; i++) {
1224                 if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) {
1225                     break;
1226                 }
1227             }
1228             if ((i > prBssInfo->auc2G_SecChnlList[0])&& (i <= CHNL_LIST_SZ_2G)){
1229                 prBssInfo->auc2G_SecChnlList[i] = ucSecChannel;
1230                 prBssInfo->auc2G_SecChnlList[0]++;
1231             }
1232         }
1233
1234         /* Update 20M bandwidth request channels */
1235         if (fg20mReq) {
1236             ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
1237             for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
1238                  i <= CHNL_LIST_SZ_2G; i++) {
1239                 if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) {
1240                     break;
1241                 }
1242             }
1243             if ((i > prBssInfo->auc2G_20mReqChnlList[0]) &&
1244                 (i <= CHNL_LIST_SZ_2G)){
1245                 prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel;
1246                 prBssInfo->auc2G_20mReqChnlList[0]++;
1247             }
1248         }
1249     }
1250     else {
1251         /* Update non-HT channel list */
1252         ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
1253         for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] &&
1254              i <= CHNL_LIST_SZ_2G; i++) {
1255             if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) {
1256                 break;
1257             }
1258         }
1259         if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1260             prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel;
1261             prBssInfo->auc2G_NonHtChnlList[0]++;
1262         }
1263
1264     }
1265
1266     return FALSE;
1267 }
1268
1269
1270 /*----------------------------------------------------------------------------*/
1271 /*!
1272 * \brief AIS or P2P GC.
1273 *
1274 * \param[in]
1275 *
1276 * \return none
1277 */
1278 /*----------------------------------------------------------------------------*/
1279 static BOOLEAN
1280 rlmRecBcnInfoForClient (
1281     P_ADAPTER_T         prAdapter,
1282     P_BSS_INFO_T        prBssInfo,
1283     P_SW_RFB_T          prSwRfb,
1284     PUINT_8             pucIE,
1285     UINT_16             u2IELength
1286     )
1287 {
1288     ASSERT(prAdapter);
1289     ASSERT(prBssInfo && prSwRfb);
1290     ASSERT(pucIE);
1291
1292 #if 0 /* SW migration 2010/8/20 */
1293     /* Note: we shall not update parameters when scanning, otherwise
1294      *       channel and bandwidth will not be correct or asserted failure
1295      *       during scanning.
1296      * Note: remove channel checking. All received Beacons should be processed
1297      *       if measurement or other actions are executed in adjacent channels
1298      *       and Beacon content checking mechanism is not disabled.
1299      */
1300     if (IS_SCAN_ACTIVE()
1301         /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */) {
1302         return FALSE;
1303     }
1304 #endif
1305
1306     /* Handle change of slot time */
1307     prBssInfo->u2CapInfo =
1308         ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->u2CapInfo;
1309     prBssInfo->fgUseShortSlotTime =
1310         (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1311
1312     rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength);
1313
1314     return TRUE;
1315 }
1316
1317 /*----------------------------------------------------------------------------*/
1318 /*!
1319 * \brief
1320 *
1321 * \param[in]
1322 *
1323 * \return none
1324 */
1325 /*----------------------------------------------------------------------------*/
1326 VOID
1327 rlmProcessBcn (
1328     P_ADAPTER_T prAdapter,
1329     P_SW_RFB_T  prSwRfb,
1330     PUINT_8     pucIE,
1331     UINT_16     u2IELength
1332     )
1333 {
1334     P_BSS_INFO_T        prBssInfo;
1335     BOOLEAN             fgNewParameter;
1336     UINT_8              ucNetIdx;
1337
1338     ASSERT(prAdapter);
1339     ASSERT(prSwRfb);
1340     ASSERT(pucIE);
1341
1342     fgNewParameter = FALSE;
1343
1344     /* When concurrent networks exist, GO shall have the same handle as
1345      * the other BSS, so the Beacon shall be procesed for bandwidth and
1346      * protection mechanism.
1347      * Note1: we do not have 2 AP (GO) cases simultaneously now.
1348      * Note2: If we are GO, concurrent AIS AP should detect it and reflect
1349      *        action in its Beacon, so AIS STA just follows Beacon from AP.
1350      */
1351     RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) {
1352         prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
1353         ASSERT(prBssInfo);
1354
1355         if (IS_BSS_ACTIVE(prBssInfo)) {
1356             if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
1357                 prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
1358                 /* P2P client or AIS infra STA */
1359                 if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID,
1360                     ((P_WLAN_MAC_MGMT_HEADER_T)
1361                       (prSwRfb->pvHeader))->aucBSSID)) {
1362
1363                     fgNewParameter = rlmRecBcnInfoForClient(prAdapter,
1364                                         prBssInfo, prSwRfb, pucIE, u2IELength);
1365                 }
1366                 else {
1367                     fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter,
1368                                         prBssInfo, prSwRfb, pucIE, u2IELength);
1369                 }
1370             }
1371         #if CFG_ENABLE_WIFI_DIRECT
1372             else if (prAdapter->fgIsP2PRegistered &&
1373                     (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT ||
1374                     prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) {
1375                 /* AP scan to check if 20/40M bandwidth is permitted */
1376                 rlmRecBcnFromNeighborForClient(prAdapter,
1377                         prBssInfo, prSwRfb, pucIE, u2IELength);
1378             }
1379         #endif
1380             else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
1381                 /* To do: Ad-hoc */
1382             }
1383
1384             /* Appy new parameters if necessary */
1385             if (fgNewParameter) {
1386                 rlmSyncOperationParams(prAdapter, prBssInfo);
1387                 fgNewParameter = FALSE;
1388             }
1389         } /* end of IS_BSS_ACTIVE() */
1390     } /* end of RLM_NET_FOR_EACH_NO_BOW */
1391 }
1392
1393 /*----------------------------------------------------------------------------*/
1394 /*!
1395 * \brief This function should be invoked after judging successful association.
1396 *
1397 * \param[in]
1398 *
1399 * \return none
1400 */
1401 /*----------------------------------------------------------------------------*/
1402 VOID
1403 rlmProcessAssocRsp (
1404     P_ADAPTER_T prAdapter,
1405     P_SW_RFB_T  prSwRfb,
1406     PUINT_8     pucIE,
1407     UINT_16     u2IELength
1408     )
1409 {
1410     P_BSS_INFO_T        prBssInfo;
1411     P_STA_RECORD_T      prStaRec;
1412     UINT_8              ucPriChannel;
1413
1414     ASSERT(prAdapter);
1415     ASSERT(prSwRfb);
1416     ASSERT(pucIE);
1417
1418     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1419     ASSERT(prStaRec);
1420     if (!prStaRec) {
1421         return;
1422     }
1423     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1424
1425     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1426     ASSERT(prStaRec == prBssInfo->prStaRecOfAP);
1427
1428     /* To do: the invoked function is used to clear all members. It may be
1429      *        done by center mechanism in invoker.
1430      */
1431     rlmBssReset(prAdapter, prBssInfo);
1432
1433     prBssInfo->fgUseShortSlotTime =
1434         (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1435
1436     if ((ucPriChannel =
1437          rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength)) > 0) {
1438         prBssInfo->ucPrimaryChannel = ucPriChannel;
1439     }
1440
1441     if (!RLM_NET_IS_11N(prBssInfo) ||
1442         !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
1443         prBssInfo->fg40mBwAllowed = FALSE;
1444     }
1445
1446     /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which
1447      *       shall be invoked afterwards.
1448      *       Update channel, bandwidth and protection mode by nicUpdateBss()
1449      */
1450 }
1451
1452 /*----------------------------------------------------------------------------*/
1453 /*!
1454 * \brief This function should be invoked after judging successful association.
1455 *
1456 * \param[in]
1457 *
1458 * \return none
1459 */
1460 /*----------------------------------------------------------------------------*/
1461 VOID
1462 rlmFillSyncCmdParam (
1463     P_CMD_SET_BSS_RLM_PARAM_T   prCmdBody,
1464     P_BSS_INFO_T                prBssInfo
1465     )
1466 {
1467     ASSERT(prCmdBody && prBssInfo);
1468     if (!prCmdBody || !prBssInfo) {
1469         return;
1470     }
1471
1472     prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
1473     prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand;
1474     prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
1475     prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO;
1476     prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode;
1477     prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode;
1478     prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode;
1479     prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode;
1480     prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3;
1481     prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2;
1482     prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1;
1483     prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble;
1484     prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime;
1485     prCmdBody->ucCheckId = 0x72;
1486
1487     if (RLM_NET_PARAM_VALID(prBssInfo)) {
1488         DBGLOG(RLM, INFO, ("N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n",
1489             prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand,
1490             prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco,
1491             prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode,
1492             prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime,
1493             prCmdBody->ucUseShortPreamble));
1494     }
1495     else {
1496         DBGLOG(RLM, INFO, ("N=%d closed\n", prCmdBody->ucNetTypeIndex));
1497     }
1498 }
1499
1500 /*----------------------------------------------------------------------------*/
1501 /*!
1502 * \brief This function will operation parameters based on situations of
1503 *        concurrent networks. Channel, bandwidth, protection mode, supported
1504 *        rate will be modified.
1505 *
1506 * \param[in]
1507 *
1508 * \return none
1509 */
1510 /*----------------------------------------------------------------------------*/
1511 VOID
1512 rlmSyncOperationParams (
1513     P_ADAPTER_T     prAdapter,
1514     P_BSS_INFO_T    prBssInfo
1515     )
1516 {
1517     P_CMD_SET_BSS_RLM_PARAM_T   prCmdBody;
1518     WLAN_STATUS                 rStatus;
1519
1520     ASSERT(prAdapter);
1521     ASSERT(prBssInfo);
1522
1523     prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T)
1524         cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T));
1525     ASSERT(prCmdBody);
1526
1527     /* To do: exception handle */
1528     if (!prCmdBody) {
1529         DBGLOG(RLM, WARN, ("No buf for sync RLM params (Net=%d)\n",
1530             prBssInfo->ucNetTypeIndex));
1531         return;
1532     }
1533
1534     rlmFillSyncCmdParam(prCmdBody, prBssInfo);
1535
1536     rStatus = wlanSendSetQueryCmd (
1537                 prAdapter,                  /* prAdapter */
1538                 CMD_ID_SET_BSS_RLM_PARAM,   /* ucCID */
1539                 TRUE,                       /* fgSetQuery */
1540                 FALSE,                      /* fgNeedResp */
1541                 FALSE,                      /* fgIsOid */
1542                 NULL,                       /* pfCmdDoneHandler */
1543                 NULL,                       /* pfCmdTimeoutHandler */
1544                 sizeof(CMD_SET_BSS_RLM_PARAM_T),    /* u4SetQueryInfoLen */
1545                 (PUINT_8) prCmdBody,        /* pucInfoBuffer */
1546                 NULL,                       /* pvSetQueryBuffer */
1547                 0                           /* u4SetQueryBufferLen */
1548                 );
1549
1550     ASSERT(rStatus == WLAN_STATUS_PENDING);
1551
1552     cnmMemFree(prAdapter, prCmdBody);
1553 }
1554
1555 #if CFG_SUPPORT_AAA
1556 /*----------------------------------------------------------------------------*/
1557 /*!
1558 * \brief This function should be invoked after judging successful association.
1559 *
1560 * \param[in]
1561 *
1562 * \return none
1563 */
1564 /*----------------------------------------------------------------------------*/
1565 VOID
1566 rlmProcessAssocReq (
1567     P_ADAPTER_T prAdapter,
1568     P_SW_RFB_T  prSwRfb,
1569     PUINT_8     pucIE,
1570     UINT_16     u2IELength
1571     )
1572 {
1573     P_BSS_INFO_T        prBssInfo;
1574     P_STA_RECORD_T      prStaRec;
1575     UINT_16             u2Offset;
1576     P_IE_HT_CAP_T       prHtCap;
1577
1578     ASSERT(prAdapter);
1579     ASSERT(prSwRfb);
1580     ASSERT(pucIE);
1581
1582     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1583     ASSERT(prStaRec);
1584     if (!prStaRec) {
1585         return;
1586     }
1587     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1588
1589     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1590
1591     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1592         switch (IE_ID(pucIE)) {
1593         case ELEM_ID_HT_CAP:
1594             if (!RLM_NET_IS_11N(prBssInfo) ||
1595                 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1596                 break;
1597             }
1598             prHtCap = (P_IE_HT_CAP_T) pucIE;
1599             prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
1600             prStaRec->fgSupMcs32 =
1601                 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32/8] & BIT(0)) ?
1602                 TRUE : FALSE;
1603
1604             prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
1605             prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
1606             prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
1607             prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
1608             prStaRec->ucAselCap = prHtCap->ucAselCap;
1609             break;
1610
1611         default:
1612             break;
1613         } /* end of switch */
1614     } /* end of IE_FOR_EACH */
1615 }
1616 #endif /* CFG_SUPPORT_AAA */
1617
1618 /*----------------------------------------------------------------------------*/
1619 /*!
1620 * \brief It is for both STA and AP modes
1621 *
1622 * \param[in]
1623 *
1624 * \return none
1625 */
1626 /*----------------------------------------------------------------------------*/
1627 VOID
1628 rlmBssInitForAPandIbss (
1629     P_ADAPTER_T     prAdapter,
1630     P_BSS_INFO_T    prBssInfo
1631     )
1632 {
1633     ASSERT(prAdapter);
1634     ASSERT(prBssInfo);
1635
1636 #if CFG_ENABLE_WIFI_DIRECT
1637     if (prAdapter->fgIsP2PRegistered &&
1638         prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1639
1640         rlmBssInitForAP(prAdapter, prBssInfo);
1641     }
1642 #endif
1643 }
1644
1645 /*----------------------------------------------------------------------------*/
1646 /*!
1647 * \brief It is for both STA and AP modes
1648 *
1649 * \param[in]
1650 *
1651 * \return none
1652 */
1653 /*----------------------------------------------------------------------------*/
1654 VOID
1655 rlmBssAborted (
1656     P_ADAPTER_T     prAdapter,
1657     P_BSS_INFO_T    prBssInfo
1658     )
1659 {
1660     ASSERT(prAdapter);
1661     ASSERT(prBssInfo);
1662
1663     rlmBssReset(prAdapter, prBssInfo);
1664
1665     prBssInfo->fg40mBwAllowed = FALSE;
1666     prBssInfo->fgAssoc40mBwAllowed = FALSE;
1667
1668     /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so
1669      * the sync CMD is not needed here.
1670      */
1671 }
1672
1673 /*----------------------------------------------------------------------------*/
1674 /*!
1675 * \brief All RLM timers will also be stopped.
1676 *
1677 * \param[in]
1678 *
1679 * \return none
1680 */
1681 /*----------------------------------------------------------------------------*/
1682 static VOID
1683 rlmBssReset (
1684     P_ADAPTER_T         prAdapter,
1685     P_BSS_INFO_T        prBssInfo
1686     )
1687 {
1688     ASSERT(prAdapter);
1689     ASSERT(prBssInfo);
1690
1691     /* HT related parameters */
1692     prBssInfo->ucHtOpInfo1 = 0;         /* RIFS disabled. 20MHz */
1693     prBssInfo->u2HtOpInfo2 = 0;
1694     prBssInfo->u2HtOpInfo3 = 0;
1695
1696     prBssInfo->eBssSCO = 0;
1697     prBssInfo->fgErpProtectMode = 0;
1698     prBssInfo->eHtProtectMode = 0;
1699     prBssInfo->eGfOperationMode = 0;
1700     prBssInfo->eRifsOperationMode = 0;
1701
1702     /* OBSS related parameters */
1703     prBssInfo->auc2G_20mReqChnlList[0] = 0;
1704     prBssInfo->auc2G_NonHtChnlList[0] = 0;
1705     prBssInfo->auc2G_PriChnlList[0] = 0;
1706     prBssInfo->auc2G_SecChnlList[0] = 0;
1707     prBssInfo->auc5G_20mReqChnlList[0] = 0;
1708     prBssInfo->auc5G_NonHtChnlList[0] = 0;
1709     prBssInfo->auc5G_PriChnlList[0] = 0;
1710     prBssInfo->auc5G_SecChnlList[0] = 0;
1711
1712     /* All RLM timers will also be stopped */
1713     cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer);
1714     prBssInfo->u2ObssScanInterval = 0;
1715
1716     prBssInfo->fgObssErpProtectMode = 0;       /* GO only */
1717     prBssInfo->eObssHtProtectMode = 0;         /* GO only */
1718     prBssInfo->eObssGfOperationMode = 0;       /* GO only */
1719     prBssInfo->fgObssRifsOperationMode = 0;    /* GO only */
1720     prBssInfo->fgObssActionForcedTo20M = 0;    /* GO only */
1721     prBssInfo->fgObssBeaconForcedTo20M = 0;    /* GO only */
1722 }
1723