2b283564ea0b7f77b8bbebe4249c4f9de17f96f1
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / 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
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 #if 1
713                 if(prMsduInfo->ucNetworkType==NETWORK_TYPE_P2P_INDEX)
714                         {
715                                 DBGLOG(AIS, WARN,("Assoc:Force P2P BW to 20\n"));
716                                 prBssInfo->fgAssoc40mBwAllowed=FALSE;
717                         }
718 #endif
719
720
721     fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
722
723     prHtCap = (P_IE_HT_CAP_T)
724               (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
725
726     /* Add HT capabilities IE */
727     prHtCap->ucId = ELEM_ID_HT_CAP;
728     prHtCap->ucLength = sizeof(IE_HT_CAP_T) - ELEM_HDR_LEN;
729
730     prHtCap->u2HtCapInfo = HT_CAP_INFO_DEFAULT_VAL;
731     if (!fg40mAllowed) {
732         prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH |
733             HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M);
734     }
735     if (prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled) {
736         prHtCap->u2HtCapInfo &=
737             ~(HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M);
738     }
739
740     if(prAdapter->rWifiVar.u8SupportRxSgi20 == 2) {
741         prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_20M);
742     }
743     if(prAdapter->rWifiVar.u8SupportRxSgi40 == 2) {
744         prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_SHORT_GI_40M);
745     }
746     if(prAdapter->rWifiVar.u8SupportRxGf == 2) {
747         prHtCap->u2HtCapInfo &= ~(HT_CAP_INFO_HT_GF);
748     }
749
750     prHtCap->ucAmpduParam = AMPDU_PARAM_DEFAULT_VAL;
751
752     prSupMcsSet = &prHtCap->rSupMcsSet;
753     kalMemZero((PVOID)&prSupMcsSet->aucRxMcsBitmask[0],
754                 SUP_MCS_RX_BITMASK_OCTET_NUM);
755
756     prSupMcsSet->aucRxMcsBitmask[0] = BITS(0, 7);
757
758     if (fg40mAllowed) {
759         prSupMcsSet->aucRxMcsBitmask[32/8] = BIT(0); /* MCS32 */
760     }
761     prSupMcsSet->u2RxHighestSupportedRate = SUP_MCS_RX_DEFAULT_HIGHEST_RATE;
762     prSupMcsSet->u4TxRateInfo = SUP_MCS_TX_DEFAULT_VAL;
763
764     prHtCap->u2HtExtendedCap = HT_EXT_CAP_DEFAULT_VAL;
765     if (!fg40mAllowed || prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
766         prHtCap->u2HtExtendedCap &=
767             ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE);
768     }
769
770     prHtCap->u4TxBeamformingCap = TX_BEAMFORMING_CAP_DEFAULT_VAL;
771
772     prHtCap->ucAselCap = ASEL_CAP_DEFAULT_VAL;
773
774
775     ASSERT(IE_SIZE(prHtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP));
776
777     prMsduInfo->u2FrameLength += IE_SIZE(prHtCap);
778 }
779
780 /*----------------------------------------------------------------------------*/
781 /*!
782 * \brief
783 *
784 * \param[in]
785 *
786 * \return none
787 */
788 /*----------------------------------------------------------------------------*/
789 static VOID
790 rlmFillExtCapIE (
791     P_ADAPTER_T     prAdapter,
792     P_BSS_INFO_T    prBssInfo,
793     P_MSDU_INFO_T   prMsduInfo
794     )
795 {
796     P_EXT_CAP_T     prExtCap;
797     BOOLEAN         fg40mAllowed;
798
799     ASSERT(prAdapter);
800     ASSERT(prMsduInfo);
801
802     fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed;
803
804     /* Add Extended Capabilities IE */
805     prExtCap = (P_EXT_CAP_T)
806                (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
807
808     prExtCap->ucId = ELEM_ID_EXTENDED_CAP;
809     prExtCap->ucLength = 1;
810     prExtCap->aucCapabilities[0] = ELEM_EXT_CAP_DEFAULT_VAL;
811
812     if (!fg40mAllowed) {
813         prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_20_40_COEXIST_SUPPORT;
814     }
815
816     if (prBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
817         prExtCap->aucCapabilities[0] &= ~ELEM_EXT_CAP_PSMP_CAP;
818     }
819
820     ASSERT(IE_SIZE(prExtCap) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP));
821
822     prMsduInfo->u2FrameLength += IE_SIZE(prExtCap);
823 }
824
825 /*----------------------------------------------------------------------------*/
826 /*!
827 * \brief
828 *
829 * \param[in]
830 *
831 * \return none
832 */
833 /*----------------------------------------------------------------------------*/
834 static VOID
835 rlmFillHtOpIE (
836     P_ADAPTER_T     prAdapter,
837     P_BSS_INFO_T    prBssInfo,
838     P_MSDU_INFO_T   prMsduInfo
839     )
840 {
841     P_IE_HT_OP_T        prHtOp;
842     UINT_16             i;
843
844     ASSERT(prAdapter);
845     ASSERT(prBssInfo);
846     ASSERT(prMsduInfo);
847
848     prHtOp = (P_IE_HT_OP_T)
849              (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength);
850
851     /* Add HT operation IE */
852     prHtOp->ucId = ELEM_ID_HT_OP;
853     prHtOp->ucLength = sizeof(IE_HT_OP_T) - ELEM_HDR_LEN;
854
855     /* RIFS and 20/40 bandwidth operations are included */
856     prHtOp->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
857     prHtOp->ucInfo1 = prBssInfo->ucHtOpInfo1;
858
859     /* Decide HT protection mode field */
860     if (prBssInfo->eHtProtectMode == HT_PROTECT_MODE_NON_HT) {
861         prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_HT;
862     }
863     else if (prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
864         prHtOp->u2Info2 = (UINT_8) HT_PROTECT_MODE_NON_MEMBER;
865     }
866     else {
867         /* It may be SYS_PROTECT_MODE_NONE or SYS_PROTECT_MODE_20M */
868         prHtOp->u2Info2 = (UINT_8) prBssInfo->eHtProtectMode;
869     }
870
871     if (prBssInfo->eGfOperationMode != GF_MODE_NORMAL) {
872         /* It may be GF_MODE_PROTECT or GF_MODE_DISALLOWED
873          * Note: it will also be set in ad-hoc network
874          */
875         prHtOp->u2Info2 |= HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
876     }
877
878     if (0 /* Regulatory class 16 */ &&
879         prBssInfo->eObssHtProtectMode == HT_PROTECT_MODE_NON_MEMBER) {
880         /* (TBD) It is HT_PROTECT_MODE_NON_MEMBER, so require protection
881          * although it is possible to have no protection by spec.
882          */
883         prHtOp->u2Info2 |= HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
884     }
885
886     prHtOp->u2Info3 = prBssInfo->u2HtOpInfo3;   /* To do: handle L-SIG TXOP */
887
888     /* No basic MCSx are needed temporarily */
889     for (i = 0; i < 16; i++) {
890         prHtOp->aucBasicMcsSet[i] = 0;
891     }
892
893     ASSERT(IE_SIZE(prHtOp) <= (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP));
894
895     prMsduInfo->u2FrameLength += IE_SIZE(prHtOp);
896 }
897
898 /*----------------------------------------------------------------------------*/
899 /*!
900 * \brief This function should be invoked to update parameters of associated AP.
901 *        (Association response and Beacon)
902 *
903 * \param[in]
904 *
905 * \return none
906 */
907 /*----------------------------------------------------------------------------*/
908 static UINT_8
909 rlmRecIeInfoForClient (
910     P_ADAPTER_T         prAdapter,
911     P_BSS_INFO_T        prBssInfo,
912     PUINT_8             pucIE,
913     UINT_16             u2IELength
914     )
915 {
916     UINT_16                 u2Offset;
917     P_STA_RECORD_T          prStaRec;
918     P_IE_HT_CAP_T           prHtCap;
919     P_IE_HT_OP_T            prHtOp;
920     P_IE_OBSS_SCAN_PARAM_T  prObssScnParam;
921     UINT_8                  ucERP, ucPrimaryChannel;
922 #if CFG_SUPPORT_QUIET && 0
923     BOOLEAN                 fgHasQuietIE = FALSE;
924 #endif
925
926     ASSERT(prAdapter);
927     ASSERT(prBssInfo);
928     ASSERT(pucIE);
929
930     prStaRec = prBssInfo->prStaRecOfAP;
931     ASSERT(prStaRec);
932     if (!prStaRec) {
933         return 0;
934     }
935
936     prBssInfo->fgUseShortPreamble = prBssInfo->fgIsShortPreambleAllowed;
937     ucPrimaryChannel = 0;
938     prObssScnParam = NULL;
939
940     /* Note: HT-related members in staRec may not be zero before, so
941      *       if following IE does not exist, they are still not zero.
942      *       These HT-related parameters are vaild only when the corresponding
943      *       BssInfo supports 802.11n, i.e., RLM_NET_IS_11N()
944      */
945     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
946         switch (IE_ID(pucIE)) {
947         case ELEM_ID_HT_CAP:
948             if (!RLM_NET_IS_11N(prBssInfo) ||
949                 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
950                 break;
951             }
952             prHtCap = (P_IE_HT_CAP_T) pucIE;
953             prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
954             prStaRec->fgSupMcs32 =
955                 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32/8] & BIT(0)) ?
956                 TRUE : FALSE;
957
958             prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
959             prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
960             prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
961             prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
962             prStaRec->ucAselCap = prHtCap->ucAselCap;
963             break;
964
965         case ELEM_ID_HT_OP:
966             if (!RLM_NET_IS_11N(prBssInfo) ||
967                 IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
968                 break;
969             }
970             prHtOp = (P_IE_HT_OP_T) pucIE;
971             /* Workaround that some APs fill primary channel field by its
972              * secondary channel, but its DS IE is correct 20110610
973              */
974             if (ucPrimaryChannel == 0) {
975                 ucPrimaryChannel = prHtOp->ucPrimaryChannel;
976             }
977             prBssInfo->ucHtOpInfo1 = prHtOp->ucInfo1;
978             prBssInfo->u2HtOpInfo2 = prHtOp->u2Info2;
979             prBssInfo->u2HtOpInfo3 = prHtOp->u2Info3;
980
981             if (!prBssInfo->fg40mBwAllowed) {
982                 prBssInfo->ucHtOpInfo1 &=
983                     ~(HT_OP_INFO1_SCO | HT_OP_INFO1_STA_CHNL_WIDTH);
984             }
985
986             if ((prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
987                 prBssInfo->eBssSCO = (ENUM_CHNL_EXT_T)
988                         (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_SCO);
989             }
990
991             prBssInfo->eHtProtectMode = (ENUM_HT_PROTECT_MODE_T)
992                 (prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_HT_PROTECTION);
993
994             /* To do: process regulatory class 16 */
995             if ((prBssInfo->u2HtOpInfo2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT)
996                 && 0 /* && regulatory class is 16 */) {
997                 prBssInfo->eGfOperationMode = GF_MODE_DISALLOWED;
998             }
999             else if (prBssInfo->u2HtOpInfo2&HT_OP_INFO2_NON_GF_HT_STA_PRESENT) {
1000                 prBssInfo->eGfOperationMode = GF_MODE_PROTECT;
1001             }
1002             else {
1003                 prBssInfo->eGfOperationMode = GF_MODE_NORMAL;
1004             }
1005
1006             prBssInfo->eRifsOperationMode =
1007                 (prBssInfo->ucHtOpInfo1 & HT_OP_INFO1_RIFS_MODE) ?
1008                 RIFS_MODE_NORMAL : RIFS_MODE_DISALLOWED;
1009
1010             break;
1011
1012         case ELEM_ID_20_40_BSS_COEXISTENCE:
1013             if (!RLM_NET_IS_11N(prBssInfo)) {
1014                 break;
1015             }
1016             /* To do: store if scanning exemption grant to BssInfo */
1017             break;
1018
1019         case ELEM_ID_OBSS_SCAN_PARAMS:
1020             if (!RLM_NET_IS_11N(prBssInfo) ||
1021                 IE_LEN(pucIE) != (sizeof(IE_OBSS_SCAN_PARAM_T) - 2)) {
1022                 break;
1023             }
1024             /* Store OBSS parameters to BssInfo */
1025             prObssScnParam = (P_IE_OBSS_SCAN_PARAM_T) pucIE;
1026             break;
1027
1028         case ELEM_ID_EXTENDED_CAP:
1029             if (!RLM_NET_IS_11N(prBssInfo)) {
1030                 break;
1031             }
1032             /* To do: store extended capability (PSMP, coexist) to BssInfo */
1033             break;
1034
1035         case ELEM_ID_ERP_INFO:
1036             if (IE_LEN(pucIE) != (sizeof(IE_ERP_T) - 2) ||
1037                 prBssInfo->eBand != BAND_2G4) {
1038                 break;
1039             }
1040             ucERP = ERP_INFO_IE(pucIE)->ucERP;
1041             prBssInfo->fgErpProtectMode =
1042                     (ucERP & ERP_INFO_USE_PROTECTION) ? TRUE : FALSE;
1043
1044             if (ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) {
1045                 prBssInfo->fgUseShortPreamble = FALSE;
1046             }
1047             break;
1048
1049         case ELEM_ID_DS_PARAM_SET:
1050             if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1051                 ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
1052             }
1053             break;
1054
1055     #if CFG_SUPPORT_QUIET && 0
1056         /* Note: RRM code should be moved to independent RRM function by
1057          *       component design rule. But we attach it to RLM temporarily
1058          */
1059         case ELEM_ID_QUIET:
1060             rrmQuietHandleQuietIE(prBssInfo, (P_IE_QUIET_T) pucIE);
1061             fgHasQuietIE = TRUE;
1062             break;
1063     #endif
1064         default:
1065             break;
1066         } /* end of switch */
1067     } /* end of IE_FOR_EACH */
1068
1069     /* Some AP will have wrong channel number (255) when running time.
1070      * Check if correct channel number information. 20110501
1071      */
1072     if ((prBssInfo->eBand == BAND_2G4 && ucPrimaryChannel > 14) ||
1073         (prBssInfo->eBand != BAND_2G4 && (ucPrimaryChannel >= 200 ||
1074          ucPrimaryChannel <= 14))) {
1075         ucPrimaryChannel = 0;
1076     }
1077
1078 #if CFG_SUPPORT_QUIET && 0
1079     if (!fgHasQuietIE) {
1080         rrmQuietIeNotExist(prAdapter, prBssInfo);
1081     }
1082 #endif
1083
1084     /* Check if OBSS scan process will launch */
1085     if (!prAdapter->fgEnOnlineScan || !prObssScnParam ||
1086         !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH) ||
1087         prBssInfo->eBand != BAND_2G4 || !prBssInfo->fg40mBwAllowed) {
1088
1089         /* Note: it is ok not to stop rObssScanTimer() here */
1090         prBssInfo->u2ObssScanInterval = 0;
1091     }
1092     else {
1093         if (prObssScnParam->u2TriggerScanInterval < OBSS_SCAN_MIN_INTERVAL) {
1094             prObssScnParam->u2TriggerScanInterval = OBSS_SCAN_MIN_INTERVAL;
1095         }
1096         if (prBssInfo->u2ObssScanInterval !=
1097             prObssScnParam->u2TriggerScanInterval) {
1098
1099             prBssInfo->u2ObssScanInterval =
1100                 prObssScnParam->u2TriggerScanInterval;
1101
1102             /* Start timer to trigger OBSS scanning */
1103             cnmTimerStartTimer(prAdapter, &prBssInfo->rObssScanTimer,
1104                 prBssInfo->u2ObssScanInterval * MSEC_PER_SEC);
1105         }
1106     }
1107
1108     return ucPrimaryChannel;
1109 }
1110
1111 /*----------------------------------------------------------------------------*/
1112 /*!
1113 * \brief AIS or P2P GC.
1114 *
1115 * \param[in]
1116 *
1117 * \return none
1118 */
1119 /*----------------------------------------------------------------------------*/
1120 static BOOLEAN
1121 rlmRecBcnFromNeighborForClient (
1122     P_ADAPTER_T         prAdapter,
1123     P_BSS_INFO_T        prBssInfo,
1124     P_SW_RFB_T          prSwRfb,
1125     PUINT_8             pucIE,
1126     UINT_16             u2IELength
1127     )
1128 {
1129     UINT_16             u2Offset, i;
1130     UINT_8              ucPriChannel, ucSecChannel;
1131     ENUM_CHNL_EXT_T     eSCO;
1132     BOOLEAN             fgHtBss, fg20mReq;
1133
1134     ASSERT(prAdapter);
1135     ASSERT(prBssInfo && prSwRfb);
1136     ASSERT(pucIE);
1137
1138     /* Record it to channel list to change 20/40 bandwidth */
1139     ucPriChannel = 0;
1140     eSCO = CHNL_EXT_SCN;
1141
1142     fgHtBss = FALSE;
1143     fg20mReq = FALSE;
1144
1145     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1146         switch (IE_ID(pucIE)) {
1147         case ELEM_ID_HT_CAP:
1148         {
1149             P_IE_HT_CAP_T           prHtCap;
1150
1151             if (IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1152                 break;
1153             }
1154
1155             prHtCap = (P_IE_HT_CAP_T) pucIE;
1156             if (prHtCap->u2HtCapInfo & HT_CAP_INFO_40M_INTOLERANT) {
1157                 fg20mReq = TRUE;
1158             }
1159             fgHtBss = TRUE;
1160             break;
1161         }
1162         case ELEM_ID_HT_OP:
1163         {
1164             P_IE_HT_OP_T        prHtOp;
1165
1166             if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1167                 break;
1168             }
1169
1170             prHtOp = (P_IE_HT_OP_T) pucIE;
1171             /* Workaround that some APs fill primary channel field by its
1172              * secondary channel, but its DS IE is correct 20110610
1173              */
1174             if (ucPriChannel == 0) {
1175                 ucPriChannel = prHtOp->ucPrimaryChannel;
1176             }
1177
1178             if ((prHtOp->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1179                 eSCO = (ENUM_CHNL_EXT_T) (prHtOp->ucInfo1 & HT_OP_INFO1_SCO);
1180             }
1181             break;
1182         }
1183         case ELEM_ID_20_40_BSS_COEXISTENCE:
1184         {
1185             P_IE_20_40_COEXIST_T    prCoexist;
1186
1187             if (IE_LEN(pucIE) != (sizeof(IE_20_40_COEXIST_T) - 2)) {
1188                 break;
1189             }
1190
1191             prCoexist = (P_IE_20_40_COEXIST_T) pucIE;
1192             if (prCoexist->ucData & BSS_COEXIST_40M_INTOLERANT) {
1193                 fg20mReq = TRUE;
1194             }
1195             break;
1196         }
1197         case ELEM_ID_DS_PARAM_SET:
1198             if (IE_LEN(pucIE) != (sizeof(IE_DS_PARAM_SET_T) - 2)) {
1199                 break;
1200             }
1201             ucPriChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
1202             break;
1203
1204         default:
1205             break;
1206         }
1207     }
1208
1209
1210     /* To do: Update channel list and 5G band. All channel lists have the same
1211      * update procedure. We should give it the entry pointer of desired
1212      * channel list.
1213      */
1214     if (HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr) != BAND_2G4) {
1215         return FALSE;
1216     }
1217
1218     if (ucPriChannel == 0 || ucPriChannel > 14) {
1219         ucPriChannel = HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr);
1220     }
1221
1222     if (fgHtBss) {
1223         ASSERT(prBssInfo->auc2G_PriChnlList[0] <= CHNL_LIST_SZ_2G);
1224         for (i = 1; i <= prBssInfo->auc2G_PriChnlList[0] &&
1225              i <= CHNL_LIST_SZ_2G; i++) {
1226             if (prBssInfo->auc2G_PriChnlList[i] == ucPriChannel) {
1227                 break;
1228             }
1229         }
1230         if ((i > prBssInfo->auc2G_PriChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1231             prBssInfo->auc2G_PriChnlList[i] = ucPriChannel;
1232             prBssInfo->auc2G_PriChnlList[0]++;
1233         }
1234
1235         /* Update secondary channel */
1236         if (eSCO != CHNL_EXT_SCN) {
1237             ucSecChannel = (eSCO == CHNL_EXT_SCA) ?
1238                 (ucPriChannel + 4) : (ucPriChannel - 4);
1239
1240             ASSERT(prBssInfo->auc2G_SecChnlList[0] <= CHNL_LIST_SZ_2G);
1241             for (i = 1; i <= prBssInfo->auc2G_SecChnlList[0] &&
1242                  i <= CHNL_LIST_SZ_2G; i++) {
1243                 if (prBssInfo->auc2G_SecChnlList[i] == ucSecChannel) {
1244                     break;
1245                 }
1246             }
1247             if ((i > prBssInfo->auc2G_SecChnlList[0])&& (i <= CHNL_LIST_SZ_2G)){
1248                 prBssInfo->auc2G_SecChnlList[i] = ucSecChannel;
1249                 prBssInfo->auc2G_SecChnlList[0]++;
1250             }
1251         }
1252
1253         /* Update 20M bandwidth request channels */
1254         if (fg20mReq) {
1255             ASSERT(prBssInfo->auc2G_20mReqChnlList[0] <= CHNL_LIST_SZ_2G);
1256             for (i = 1; i <= prBssInfo->auc2G_20mReqChnlList[0] &&
1257                  i <= CHNL_LIST_SZ_2G; i++) {
1258                 if (prBssInfo->auc2G_20mReqChnlList[i] == ucPriChannel) {
1259                     break;
1260                 }
1261             }
1262             if ((i > prBssInfo->auc2G_20mReqChnlList[0]) &&
1263                 (i <= CHNL_LIST_SZ_2G)){
1264                 prBssInfo->auc2G_20mReqChnlList[i] = ucPriChannel;
1265                 prBssInfo->auc2G_20mReqChnlList[0]++;
1266             }
1267         }
1268     }
1269     else {
1270         /* Update non-HT channel list */
1271         ASSERT(prBssInfo->auc2G_NonHtChnlList[0] <= CHNL_LIST_SZ_2G);
1272         for (i = 1; i <= prBssInfo->auc2G_NonHtChnlList[0] &&
1273              i <= CHNL_LIST_SZ_2G; i++) {
1274             if (prBssInfo->auc2G_NonHtChnlList[i] == ucPriChannel) {
1275                 break;
1276             }
1277         }
1278         if ((i > prBssInfo->auc2G_NonHtChnlList[0]) && (i <= CHNL_LIST_SZ_2G)) {
1279             prBssInfo->auc2G_NonHtChnlList[i] = ucPriChannel;
1280             prBssInfo->auc2G_NonHtChnlList[0]++;
1281         }
1282
1283     }
1284
1285     return FALSE;
1286 }
1287
1288
1289 /*----------------------------------------------------------------------------*/
1290 /*!
1291 * \brief AIS or P2P GC.
1292 *
1293 * \param[in]
1294 *
1295 * \return none
1296 */
1297 /*----------------------------------------------------------------------------*/
1298 static BOOLEAN
1299 rlmRecBcnInfoForClient (
1300     P_ADAPTER_T         prAdapter,
1301     P_BSS_INFO_T        prBssInfo,
1302     P_SW_RFB_T          prSwRfb,
1303     PUINT_8             pucIE,
1304     UINT_16             u2IELength
1305     )
1306 {
1307     ASSERT(prAdapter);
1308     ASSERT(prBssInfo && prSwRfb);
1309     ASSERT(pucIE);
1310
1311 #if 0 /* SW migration 2010/8/20 */
1312     /* Note: we shall not update parameters when scanning, otherwise
1313      *       channel and bandwidth will not be correct or asserted failure
1314      *       during scanning.
1315      * Note: remove channel checking. All received Beacons should be processed
1316      *       if measurement or other actions are executed in adjacent channels
1317      *       and Beacon content checking mechanism is not disabled.
1318      */
1319     if (IS_SCAN_ACTIVE()
1320         /* || prBssInfo->ucPrimaryChannel != CHNL_NUM_BY_SWRFB(prSwRfb) */) {
1321         return FALSE;
1322     }
1323 #endif
1324
1325     /* Handle change of slot time */
1326     prBssInfo->u2CapInfo =
1327         ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->u2CapInfo;
1328     prBssInfo->fgUseShortSlotTime =
1329         (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1330
1331     rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength);
1332
1333     return TRUE;
1334 }
1335
1336 /*----------------------------------------------------------------------------*/
1337 /*!
1338 * \brief
1339 *
1340 * \param[in]
1341 *
1342 * \return none
1343 */
1344 /*----------------------------------------------------------------------------*/
1345 VOID
1346 rlmProcessBcn (
1347     P_ADAPTER_T prAdapter,
1348     P_SW_RFB_T  prSwRfb,
1349     PUINT_8     pucIE,
1350     UINT_16     u2IELength
1351     )
1352 {
1353     P_BSS_INFO_T        prBssInfo;
1354     BOOLEAN             fgNewParameter;
1355     UINT_8              ucNetIdx;
1356
1357     ASSERT(prAdapter);
1358     ASSERT(prSwRfb);
1359     ASSERT(pucIE);
1360
1361     fgNewParameter = FALSE;
1362
1363     /* When concurrent networks exist, GO shall have the same handle as
1364      * the other BSS, so the Beacon shall be procesed for bandwidth and
1365      * protection mechanism.
1366      * Note1: we do not have 2 AP (GO) cases simultaneously now.
1367      * Note2: If we are GO, concurrent AIS AP should detect it and reflect
1368      *        action in its Beacon, so AIS STA just follows Beacon from AP.
1369      */
1370     RLM_NET_FOR_EACH_NO_BOW(ucNetIdx) {
1371         prBssInfo = &prAdapter->rWifiVar.arBssInfo[ucNetIdx];
1372         ASSERT(prBssInfo);
1373
1374         if (IS_BSS_ACTIVE(prBssInfo)) {
1375             if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
1376                 prBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
1377                 /* P2P client or AIS infra STA */
1378                 if (EQUAL_MAC_ADDR(prBssInfo->aucBSSID,
1379                     ((P_WLAN_MAC_MGMT_HEADER_T)
1380                       (prSwRfb->pvHeader))->aucBSSID)) {
1381
1382                     fgNewParameter = rlmRecBcnInfoForClient(prAdapter,
1383                                         prBssInfo, prSwRfb, pucIE, u2IELength);
1384                 }
1385                 else {
1386                     fgNewParameter = rlmRecBcnFromNeighborForClient(prAdapter,
1387                                         prBssInfo, prSwRfb, pucIE, u2IELength);
1388                 }
1389             }
1390         #if CFG_ENABLE_WIFI_DIRECT
1391             else if (prAdapter->fgIsP2PRegistered &&
1392                     (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT ||
1393                     prBssInfo->eCurrentOPMode == OP_MODE_P2P_DEVICE)) {
1394                 /* AP scan to check if 20/40M bandwidth is permitted */
1395                 rlmRecBcnFromNeighborForClient(prAdapter,
1396                         prBssInfo, prSwRfb, pucIE, u2IELength);
1397             }
1398         #endif
1399             else if (prBssInfo->eCurrentOPMode == OP_MODE_IBSS) {
1400                 /* To do: Ad-hoc */
1401             }
1402
1403             /* Appy new parameters if necessary */
1404             if (fgNewParameter) {
1405                 rlmSyncOperationParams(prAdapter, prBssInfo);
1406                 fgNewParameter = FALSE;
1407             }
1408         } /* end of IS_BSS_ACTIVE() */
1409     } /* end of RLM_NET_FOR_EACH_NO_BOW */
1410 }
1411
1412 /*----------------------------------------------------------------------------*/
1413 /*!
1414 * \brief This function should be invoked after judging successful association.
1415 *
1416 * \param[in]
1417 *
1418 * \return none
1419 */
1420 /*----------------------------------------------------------------------------*/
1421 VOID
1422 rlmProcessAssocRsp (
1423     P_ADAPTER_T prAdapter,
1424     P_SW_RFB_T  prSwRfb,
1425     PUINT_8     pucIE,
1426     UINT_16     u2IELength
1427     )
1428 {
1429     P_BSS_INFO_T        prBssInfo;
1430     P_STA_RECORD_T      prStaRec;
1431     UINT_8              ucPriChannel;
1432
1433     ASSERT(prAdapter);
1434     ASSERT(prSwRfb);
1435     ASSERT(pucIE);
1436
1437     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1438     ASSERT(prStaRec);
1439     if (!prStaRec) {
1440         return;
1441     }
1442     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1443
1444     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1445     ASSERT(prStaRec == prBssInfo->prStaRecOfAP);
1446
1447     /* To do: the invoked function is used to clear all members. It may be
1448      *        done by center mechanism in invoker.
1449      */
1450     rlmBssReset(prAdapter, prBssInfo);
1451
1452     prBssInfo->fgUseShortSlotTime =
1453         (prBssInfo->u2CapInfo & CAP_INFO_SHORT_SLOT_TIME) ? TRUE : FALSE;
1454
1455     if ((ucPriChannel =
1456          rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength)) > 0) {
1457         prBssInfo->ucPrimaryChannel = ucPriChannel;
1458     }
1459
1460     if (!RLM_NET_IS_11N(prBssInfo) ||
1461         !(prStaRec->u2HtCapInfo & HT_CAP_INFO_SUP_CHNL_WIDTH)) {
1462         prBssInfo->fg40mBwAllowed = FALSE;
1463     }
1464
1465     /* Note: Update its capabilities to WTBL by cnmStaRecChangeState(), which
1466      *       shall be invoked afterwards.
1467      *       Update channel, bandwidth and protection mode by nicUpdateBss()
1468      */
1469 #if 1
1470         if(prStaRec->ucNetTypeIndex==NETWORK_TYPE_P2P_INDEX)
1471         {
1472                                 
1473                                 DBGLOG(AIS, WARN, ("Force P2P BW to 20\n"));
1474                                 prBssInfo->fgAssoc40mBwAllowed=FALSE;
1475         }       
1476 #endif
1477
1478
1479 }
1480
1481 /*----------------------------------------------------------------------------*/
1482 /*!
1483 * \brief This function should be invoked after judging successful association.
1484 *
1485 * \param[in]
1486 *
1487 * \return none
1488 */
1489 /*----------------------------------------------------------------------------*/
1490 VOID
1491 rlmFillSyncCmdParam (
1492     P_CMD_SET_BSS_RLM_PARAM_T   prCmdBody,
1493     P_BSS_INFO_T                prBssInfo
1494     )
1495 {
1496     ASSERT(prCmdBody && prBssInfo);
1497     if (!prCmdBody || !prBssInfo) {
1498         return;
1499     }
1500
1501     prCmdBody->ucNetTypeIndex = prBssInfo->ucNetTypeIndex;
1502     prCmdBody->ucRfBand = (UINT_8) prBssInfo->eBand;
1503     prCmdBody->ucPrimaryChannel = prBssInfo->ucPrimaryChannel;
1504     prCmdBody->ucRfSco = (UINT_8) prBssInfo->eBssSCO;
1505     prCmdBody->ucErpProtectMode = (UINT_8) prBssInfo->fgErpProtectMode;
1506     prCmdBody->ucHtProtectMode = (UINT_8) prBssInfo->eHtProtectMode;
1507     prCmdBody->ucGfOperationMode = (UINT_8) prBssInfo->eGfOperationMode;
1508     prCmdBody->ucTxRifsMode = (UINT_8) prBssInfo->eRifsOperationMode;
1509     prCmdBody->u2HtOpInfo3 = prBssInfo->u2HtOpInfo3;
1510     prCmdBody->u2HtOpInfo2 = prBssInfo->u2HtOpInfo2;
1511     prCmdBody->ucHtOpInfo1 = prBssInfo->ucHtOpInfo1;
1512     prCmdBody->ucUseShortPreamble = prBssInfo->fgUseShortPreamble;
1513     prCmdBody->ucUseShortSlotTime = prBssInfo->fgUseShortSlotTime;
1514     prCmdBody->ucCheckId = 0x72;
1515
1516     if (RLM_NET_PARAM_VALID(prBssInfo)) {
1517         DBGLOG(RLM, INFO, ("N=%d b=%d c=%d s=%d e=%d h=%d I=0x%02x l=%d p=%d\n",
1518             prCmdBody->ucNetTypeIndex, prCmdBody->ucRfBand,
1519             prCmdBody->ucPrimaryChannel, prCmdBody->ucRfSco,
1520             prCmdBody->ucErpProtectMode, prCmdBody->ucHtProtectMode,
1521             prCmdBody->ucHtOpInfo1, prCmdBody->ucUseShortSlotTime,
1522             prCmdBody->ucUseShortPreamble));
1523     }
1524     else {
1525         DBGLOG(RLM, INFO, ("N=%d closed\n", prCmdBody->ucNetTypeIndex));
1526     }
1527 }
1528
1529 /*----------------------------------------------------------------------------*/
1530 /*!
1531 * \brief This function will operation parameters based on situations of
1532 *        concurrent networks. Channel, bandwidth, protection mode, supported
1533 *        rate will be modified.
1534 *
1535 * \param[in]
1536 *
1537 * \return none
1538 */
1539 /*----------------------------------------------------------------------------*/
1540 VOID
1541 rlmSyncOperationParams (
1542     P_ADAPTER_T     prAdapter,
1543     P_BSS_INFO_T    prBssInfo
1544     )
1545 {
1546     P_CMD_SET_BSS_RLM_PARAM_T   prCmdBody;
1547     WLAN_STATUS                 rStatus;
1548
1549     ASSERT(prAdapter);
1550     ASSERT(prBssInfo);
1551
1552     prCmdBody = (P_CMD_SET_BSS_RLM_PARAM_T)
1553         cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_BSS_RLM_PARAM_T));
1554     ASSERT(prCmdBody);
1555
1556     /* To do: exception handle */
1557     if (!prCmdBody) {
1558         DBGLOG(RLM, WARN, ("No buf for sync RLM params (Net=%d)\n",
1559             prBssInfo->ucNetTypeIndex));
1560         return;
1561     }
1562
1563     rlmFillSyncCmdParam(prCmdBody, prBssInfo);
1564
1565     rStatus = wlanSendSetQueryCmd (
1566                 prAdapter,                  /* prAdapter */
1567                 CMD_ID_SET_BSS_RLM_PARAM,   /* ucCID */
1568                 TRUE,                       /* fgSetQuery */
1569                 FALSE,                      /* fgNeedResp */
1570                 FALSE,                      /* fgIsOid */
1571                 NULL,                       /* pfCmdDoneHandler */
1572                 NULL,                       /* pfCmdTimeoutHandler */
1573                 sizeof(CMD_SET_BSS_RLM_PARAM_T),    /* u4SetQueryInfoLen */
1574                 (PUINT_8) prCmdBody,        /* pucInfoBuffer */
1575                 NULL,                       /* pvSetQueryBuffer */
1576                 0                           /* u4SetQueryBufferLen */
1577                 );
1578
1579     ASSERT(rStatus == WLAN_STATUS_PENDING);
1580
1581     cnmMemFree(prAdapter, prCmdBody);
1582 }
1583
1584 #if CFG_SUPPORT_AAA
1585 /*----------------------------------------------------------------------------*/
1586 /*!
1587 * \brief This function should be invoked after judging successful association.
1588 *
1589 * \param[in]
1590 *
1591 * \return none
1592 */
1593 /*----------------------------------------------------------------------------*/
1594 VOID
1595 rlmProcessAssocReq (
1596     P_ADAPTER_T prAdapter,
1597     P_SW_RFB_T  prSwRfb,
1598     PUINT_8     pucIE,
1599     UINT_16     u2IELength
1600     )
1601 {
1602     P_BSS_INFO_T        prBssInfo;
1603     P_STA_RECORD_T      prStaRec;
1604     UINT_16             u2Offset;
1605     P_IE_HT_CAP_T       prHtCap;
1606
1607     ASSERT(prAdapter);
1608     ASSERT(prSwRfb);
1609     ASSERT(pucIE);
1610
1611     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1612     ASSERT(prStaRec);
1613     if (!prStaRec) {
1614         return;
1615     }
1616     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1617
1618     prBssInfo = &prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex];
1619
1620     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1621         switch (IE_ID(pucIE)) {
1622         case ELEM_ID_HT_CAP:
1623             if (!RLM_NET_IS_11N(prBssInfo) ||
1624                 IE_LEN(pucIE) != (sizeof(IE_HT_CAP_T) - 2)) {
1625                 break;
1626             }
1627             prHtCap = (P_IE_HT_CAP_T) pucIE;
1628             prStaRec->ucMcsSet = prHtCap->rSupMcsSet.aucRxMcsBitmask[0];
1629             prStaRec->fgSupMcs32 =
1630                 (prHtCap->rSupMcsSet.aucRxMcsBitmask[32/8] & BIT(0)) ?
1631                 TRUE : FALSE;
1632
1633             prStaRec->u2HtCapInfo = prHtCap->u2HtCapInfo;
1634             prStaRec->ucAmpduParam = prHtCap->ucAmpduParam;
1635             prStaRec->u2HtExtendedCap = prHtCap->u2HtExtendedCap;
1636             prStaRec->u4TxBeamformingCap = prHtCap->u4TxBeamformingCap;
1637             prStaRec->ucAselCap = prHtCap->ucAselCap;
1638             break;
1639
1640         default:
1641             break;
1642         } /* end of switch */
1643     } /* end of IE_FOR_EACH */
1644 }
1645 #endif /* CFG_SUPPORT_AAA */
1646
1647 /*----------------------------------------------------------------------------*/
1648 /*!
1649 * \brief It is for both STA and AP modes
1650 *
1651 * \param[in]
1652 *
1653 * \return none
1654 */
1655 /*----------------------------------------------------------------------------*/
1656 VOID
1657 rlmBssInitForAPandIbss (
1658     P_ADAPTER_T     prAdapter,
1659     P_BSS_INFO_T    prBssInfo
1660     )
1661 {
1662     ASSERT(prAdapter);
1663     ASSERT(prBssInfo);
1664
1665 #if CFG_ENABLE_WIFI_DIRECT
1666     if (prAdapter->fgIsP2PRegistered &&
1667         prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1668
1669         rlmBssInitForAP(prAdapter, prBssInfo);
1670     }
1671 #endif
1672 }
1673
1674 /*----------------------------------------------------------------------------*/
1675 /*!
1676 * \brief It is for both STA and AP modes
1677 *
1678 * \param[in]
1679 *
1680 * \return none
1681 */
1682 /*----------------------------------------------------------------------------*/
1683 VOID
1684 rlmBssAborted (
1685     P_ADAPTER_T     prAdapter,
1686     P_BSS_INFO_T    prBssInfo
1687     )
1688 {
1689     ASSERT(prAdapter);
1690     ASSERT(prBssInfo);
1691
1692     rlmBssReset(prAdapter, prBssInfo);
1693
1694     prBssInfo->fg40mBwAllowed = FALSE;
1695     prBssInfo->fgAssoc40mBwAllowed = FALSE;
1696
1697     /* Assume FW state is updated by CMD_ID_SET_BSS_INFO, so
1698      * the sync CMD is not needed here.
1699      */
1700 }
1701
1702 /*----------------------------------------------------------------------------*/
1703 /*!
1704 * \brief All RLM timers will also be stopped.
1705 *
1706 * \param[in]
1707 *
1708 * \return none
1709 */
1710 /*----------------------------------------------------------------------------*/
1711 static VOID
1712 rlmBssReset (
1713     P_ADAPTER_T         prAdapter,
1714     P_BSS_INFO_T        prBssInfo
1715     )
1716 {
1717     ASSERT(prAdapter);
1718     ASSERT(prBssInfo);
1719
1720     /* HT related parameters */
1721     prBssInfo->ucHtOpInfo1 = 0;         /* RIFS disabled. 20MHz */
1722     prBssInfo->u2HtOpInfo2 = 0;
1723     prBssInfo->u2HtOpInfo3 = 0;
1724
1725     prBssInfo->eBssSCO = 0;
1726     prBssInfo->fgErpProtectMode = 0;
1727     prBssInfo->eHtProtectMode = 0;
1728     prBssInfo->eGfOperationMode = 0;
1729     prBssInfo->eRifsOperationMode = 0;
1730
1731     /* OBSS related parameters */
1732     prBssInfo->auc2G_20mReqChnlList[0] = 0;
1733     prBssInfo->auc2G_NonHtChnlList[0] = 0;
1734     prBssInfo->auc2G_PriChnlList[0] = 0;
1735     prBssInfo->auc2G_SecChnlList[0] = 0;
1736     prBssInfo->auc5G_20mReqChnlList[0] = 0;
1737     prBssInfo->auc5G_NonHtChnlList[0] = 0;
1738     prBssInfo->auc5G_PriChnlList[0] = 0;
1739     prBssInfo->auc5G_SecChnlList[0] = 0;
1740
1741     /* All RLM timers will also be stopped */
1742     cnmTimerStopTimer(prAdapter, &prBssInfo->rObssScanTimer);
1743     prBssInfo->u2ObssScanInterval = 0;
1744
1745     prBssInfo->fgObssErpProtectMode = 0;       /* GO only */
1746     prBssInfo->eObssHtProtectMode = 0;         /* GO only */
1747     prBssInfo->eObssGfOperationMode = 0;       /* GO only */
1748     prBssInfo->fgObssRifsOperationMode = 0;    /* GO only */
1749     prBssInfo->fgObssActionForcedTo20M = 0;    /* GO only */
1750     prBssInfo->fgObssBeaconForcedTo20M = 0;    /* GO only */
1751 }
1752