support different wifi bt chip auto compatible
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6620 / wlan / mgmt / assoc.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/assoc.c#3 $
3 */
4
5 /*! \file   "assoc.c"
6     \brief  This file includes the association-related functions.
7
8     This file includes the association-related functions.
9 */
10
11
12
13 /*\
14 ** $Log: assoc.c $
15 **
16 ** 07 27 2012 yuche.tsai
17 ** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
18 ** Fix wifi direct connection issue.
19  *
20  * 07 17 2012 yuche.tsai
21  * NULL
22  * Let netdev bring up.
23  *
24  * 07 17 2012 yuche.tsai
25  * NULL
26  * Compile no error before trial run.
27  *
28  * 06 13 2012 yuche.tsai
29  * NULL
30  * Update maintrunk driver.
31  * Add support for driver compose assoc request frame.
32  *
33  * 06 08 2012 cp.wu
34  * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development
35  * add a pair of brace for compilation success.
36  *
37  * 06 04 2012 cp.wu
38  * [WCXRP00001245] [MT6620 Wi-Fi][Driver][Firmware] NPS Software Development
39  * discussed with WH, privacy bit in associate response is not necessary to be checked, and identified as association failure when mismatching with beacon/probe response
40  *
41  * 03 14 2012 wh.su
42  * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting
43  * Add code from 2.2
44  *
45  * 03 09 2012 terry.wu
46  * NULL
47  * Fix build error.
48  *
49  * 03 02 2012 terry.wu
50  * NULL
51  * Sync CFG80211 modification from branch 2,2.
52  *
53  * 01 16 2012 yuche.tsai
54  * NULL
55  * Update Driver for wifi driect gc join IE update issue.
56  *
57  * 11 10 2011 wh.su
58  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
59  * change the debug module level.
60  *
61  * 10 25 2011 cm.chang
62  * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
63  * Fix PhyTypeSet in STA_REC in AP mode
64  *
65  * 10 12 2011 wh.su
66  * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
67  * adding the 802.11w related function and define .
68  *
69  * 09 19 2011 yuche.tsai
70  * NULL
71  * Fix KE when enable hot-spot & any one client connect to this hot-spot.
72  *
73  * 09 14 2011 yuche.tsai
74  * NULL
75  * Add P2P IE in assoc response.
76  *
77  * 07 15 2011 terry.wu
78  * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment
79  * Update workaround for Kingnet AP.
80  *
81  * 07 15 2011 terry.wu
82  * [WCXRP00000855] [MT6620 Wi-Fi] [Driver] Workaround for Kingnet 710 AP wrong AID assignment
83  * Workaround for Kingnet 710 AP wrong AID assignment.
84  *
85  * 05 02 2011 eddie.chen
86  * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning[WCXRP00000672] [MT6620 Wi-Fi][FW] Fix the PS event allocation
87  * Check STA when rx assoc.
88  *
89  * 04 18 2011 terry.wu
90  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
91  * Remove flag CFG_WIFI_DIRECT_MOVED.
92  *
93  * 03 19 2011 yuche.tsai
94  * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue
95  * Make assoc req to append P2P IE if wifi direct is enabled.
96  *
97  * 03 17 2011 chinglan.wang
98  * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
99  * .
100  *
101  * 03 16 2011 wh.su
102  * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
103  * enable the protected while at P2P start GO, and skip some security check .
104  *
105  * 03 14 2011 wh.su
106  * [WCXRP00000545] [MT6620 Wi-Fi] [Driver] Fixed the p2p not enable, received a assoc rsp cause the rx assoc execute a null function
107  * Modify file for avoid assert at BOW recieve a assoc response frame but no p2p fucntion.
108  *
109  * 03 08 2011 terry.wu
110  * [WCXRP00000524] [MT6620 Wi-Fi][Driver] Fix p2p assoc request containing wrong IE format
111  * Fix p2p assoc request containing wrong IE format.
112  *
113  * 03 02 2011 wh.su
114  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
115  * add code to let the beacon and probe response for Auto GO WSC .
116  *
117  * 02 15 2011 yuche.tsai
118  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
119  * Fix RX disassoc issue under Hot-spot mode.
120  *
121  * 02 09 2011 wh.su
122  * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
123  * adding the code for check STA privacy bit at AP mode, .
124  *
125  * 02 08 2011 eddie.chen
126  * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
127  * Add event STA agint timeout
128  *
129  * 01 25 2011 yuche.tsai
130  * [WCXRP00000388] [Volunteer Patch][MT6620][Driver/Fw] change Station Type in station record.
131  * Change Station Type in Station Record, Modify MACRO definition for getting station type & network type index & Role.
132  *
133  * 01 12 2011 yuche.tsai
134  * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update when STA record is created under AP Mode.
135  * Update Phy Type Set. When legacy client is connected, it can use 11b rate,
136  * but if the P2P device is connected, 11b rate is not allowed.
137  *
138  * 01 11 2011 yuche.tsai
139  * [WCXRP00000353] [Volunteer Patch][MT6620][Driver] Desired Non-HT Rate Set update when STA record is created under AP Mode.
140  * Update Desired Non-HT Rate Set.
141  *
142  * 12 30 2010 eddie.chen
143  * [WCXRP00000322] Add WMM IE in beacon,
144
145 Add per station flow control when STA is in PS
146
147
148  * Recover the code that was coverwritted..
149  *
150  * 12 29 2010 eddie.chen
151  * [WCXRP00000322] Add WMM IE in beacon,
152 Add per station flow control when STA is in PS
153
154  * 1) PS flow control event
155  *
156  * 2) WMM IE in beacon, assoc resp, probe resp
157  *
158  * 11 04 2010 wh.su
159  * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
160  * adding the p2p random ssid support.
161  *
162  * 10 18 2010 cp.wu
163  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
164  * use definition macro to replace hard-coded constant
165  *
166  * 09 28 2010 wh.su
167  * NULL
168  * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
169  *
170  * 09 27 2010 chinghwa.yu
171  * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
172  * Update BCM/BoW design and settings.
173  *
174  * 09 16 2010 cm.chang
175  * NULL
176  * Change conditional compiling options for BOW
177  *
178  * 09 03 2010 kevin.huang
179  * NULL
180  * Refine #include sequence and solve recursive/nested #include issue
181  *
182  * 09 01 2010 wh.su
183  * NULL
184  * adding the wapi support for integration test.
185  *
186  * 08 30 2010 cp.wu
187  * NULL
188  * eliminate klockwork errors
189  *
190  * 08 16 2010 yuche.tsai
191  * NULL
192  * Add SSID IE in assoc req frame which is sent by P2P GC.
193  *
194  * 08 16 2010 kevin.huang
195  * NULL
196  * Refine AAA functions
197  *
198  * 08 03 2010 cp.wu
199  * NULL
200  * surpress compilation warning.
201  *
202  * 07 20 2010 wh.su
203  *
204  * adding the wapi code.
205  *
206  * 07 09 2010 yarco.yang
207  *
208  * [MT6620 and MT5931] SW Migration: Add ADDBA support
209  *
210  * 07 08 2010 cp.wu
211  *
212  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
213  *
214  * 07 08 2010 cp.wu
215  * [WPD00003833][MT6620 and MT5931] Driver migration
216  * take use of RLM module for parsing/generating HT IEs for 11n capability
217  *
218  * 07 01 2010 cp.wu
219  * [WPD00003833][MT6620 and MT5931] Driver migration
220  * comment out RSN IE generation by CFG_RSN_MIGRATION compilation flag.
221  *
222  * 06 28 2010 cp.wu
223  * [WPD00003833][MT6620 and MT5931] Driver migration
224  * send MMPDU in basic rate.
225  *
226  * 06 21 2010 cp.wu
227  * [WPD00003833][MT6620 and MT5931] Driver migration
228  * add scan_fsm into building.
229  *
230  * 06 21 2010 cp.wu
231  * [WPD00003833][MT6620 and MT5931] Driver migration
232  * specify correct value for management frames.
233  *
234  * 06 18 2010 cm.chang
235  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
236  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
237  *
238  * 06 18 2010 wh.su
239  * [WPD00003840][MT6620 5931] Security migration
240  * migration from MT6620 firmware.
241  *
242  * 06 15 2010 cp.wu
243  * [WPD00003833][MT6620 and MT5931] Driver migration
244  * revised.
245  *
246  * 06 14 2010 cp.wu
247  * [WPD00003833][MT6620 and MT5931] Driver migration
248  * add management dispatching function table.
249  *
250  * 06 11 2010 cp.wu
251  * [WPD00003833][MT6620 and MT5931] Driver migration
252  * auth.c is migrated.
253  *
254  * 06 11 2010 cp.wu
255  * [WPD00003833][MT6620 and MT5931] Driver migration
256  * 1) migrate assoc.c.
257  * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
258  * 3) add configuration options for CNM_MEM and RSN modules
259  * 4) add data path for management frames
260  * 5) eliminate rPacketInfo of MSDU_INFO_T
261  *
262  * 05 24 2010 kevin.huang
263  * [BORA00000794][WIFISYS][New Feature]Power Management Support
264  * Update assocProcessRxAssocReqFrame() to avoid redundant SSID IE {0,0} for IOT.
265  *
266  * 05 14 2010 kevin.huang
267  * [BORA00000794][WIFISYS][New Feature]Power Management Support
268  * Fix compile warning - macro > 10 line, initial value of an array
269  *
270  * 04 24 2010 cm.chang
271  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
272  * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
273  *
274  * 04 22 2010 cm.chang
275  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
276  * First draft code to support protection in AP mode
277  *
278  * 04 19 2010 kevin.huang
279  * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
280  * Add Beacon Timeout Support
281  *  *  *  *  *  *  *  *  and will send Null frame to diagnose connection
282  *
283  * 04 16 2010 wh.su
284  * [BORA00000680][MT6620] Support the statistic for Microsoft os query
285  * adding the wpa-none for ibss beacon.
286  *
287  * 03 25 2010 cm.chang
288  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
289  * Remove compiling warning
290  *
291  * 03 24 2010 cm.chang
292  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
293  * Not carry  HT cap when being associated with b/g only AP
294  *
295  * 02 04 2010 kevin.huang
296  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
297  * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
298  *
299  * 01 28 2010 wh.su
300  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
301  * fixed the compiling warning.u1rwduu`wvpghlqg|rm+vp
302  *
303  * 01 27 2010 wh.su
304  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
305  * add and fixed some security function.
306  *
307  * 01 11 2010 kevin.huang
308  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
309  * Add Deauth and Disassoc Handler
310  *
311  * 01 07 2010 kevin.huang
312  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
313  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
314  * Update Assoc ID for PS
315  *
316  * 01 04 2010 tehuang.liu
317  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
318  * For working out the first connection Chariot-verified version
319  *
320  * 12 18 2009 cm.chang
321  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
322  * .
323  *
324  * Dec 12 2009 mtk01104
325  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
326  * Use new constant definition ELEM_MAX_LEN_EXT_CAP
327  *
328  * Dec 9 2009 mtk01104
329  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
330  * Modify assoc req IE talbe for HT cap IE
331  *
332  * Dec 7 2009 mtk01461
333  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
334  * update the assocComposeReAssocReqFrameHeader() and fix the u2EstimatedFrameLen in assocSendReAssocReqFrame()
335  *
336  * Dec 7 2009 mtk01088
337  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
338  * remove some space line
339  *
340  * Dec 7 2009 mtk01088
341  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
342  * adding the sending disassoc frame function
343  *
344  * Dec 4 2009 mtk01088
345  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
346  * adding the txassocReq IE table, adding for WPA/RSN
347  *
348  * Dec 3 2009 mtk01461
349  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
350  * Fix eNetType not init in send AssocReq function
351  *
352  * Dec 3 2009 mtk01461
353  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
354  * Integrate the send Assoc with TXM
355  *
356  * Dec 1 2009 mtk01088
357  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
358  * adding the code to indicate the assoc request and assoc response (now disable)
359  *
360  * Nov 24 2009 mtk01461
361  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
362  * Remove unused variables
363  *
364  * Nov 23 2009 mtk01461
365  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
366  *
367 */
368
369 /*******************************************************************************
370 *                         C O M P I L E R   F L A G S
371 ********************************************************************************
372 */
373
374 /*******************************************************************************
375 *                    E X T E R N A L   R E F E R E N C E S
376 ********************************************************************************
377 */
378 #include "precomp.h"
379
380 /*******************************************************************************
381 *                              C O N S T A N T S
382 ********************************************************************************
383 */
384
385 /*******************************************************************************
386 *                             D A T A   T Y P E S
387 ********************************************************************************
388 */
389
390 /*******************************************************************************
391 *                            P U B L I C   D A T A
392 ********************************************************************************
393 */
394 APPEND_VAR_IE_ENTRY_T txAssocReqIETable[] = {
395     { (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP),    NULL,     rlmReqGenerateHtCapIE },/* 45 */
396 #if CFG_SUPPORT_WPS2
397         { (ELEM_HDR_LEN + ELEM_MAX_LEN_WSC),   NULL,      rsnGenerateWSCIE },     /* 221 */
398 #endif
399 #if CFG_SUPPORT_WAPI
400     { (ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI),   NULL,    wapiGenerateWAPIIE },   /* 68 */
401 #endif
402 #if CFG_RSN_MIGRATION
403     { (ELEM_HDR_LEN + ELEM_MAX_LEN_WPA),   NULL,        rsnGenerateWPAIE },     /* 221 */
404 #endif
405     { (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP),   NULL,    rlmReqGenerateExtCapIE },  /* 127 */
406     { (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO),   NULL,   mqmGenerateWmmInfoIE },  /* 221 */
407 #if CFG_RSN_MIGRATION
408     { (ELEM_HDR_LEN + ELEM_MAX_LEN_RSN),   NULL,        rsnGenerateRSNIE },    /* 48 */
409 #endif
410 };
411
412 #if CFG_SUPPORT_AAA
413 VERIFY_IE_ENTRY_T rxAssocReqIETable[] = {
414     { ELEM_ID_RESERVED,                         NULL                    } /* 255 */
415 };
416
417
418 APPEND_VAR_IE_ENTRY_T txAssocRespIETable[] = {
419     { (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP),     NULL,     rlmRspGenerateErpIE   },        /* 42 */
420     { (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP),      NULL,     rlmRspGenerateHtCapIE   },      /* 45 */
421     { (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP),     NULL,     rlmRspGenerateHtOpIE   },       /* 61 */
422 #if CFG_ENABLE_WIFI_DIRECT
423     { (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN),  NULL,   rlmRspGenerateObssScanIE   },   /* 74 */
424     { (0),         p2pFuncCalculateP2p_IELenForAssocRsp,      p2pFuncGenerateP2p_IEForAssocRsp }, /* 221 */
425 #if CFG_SUPPORT_WFD
426     { (0),         wfdFuncCalculateWfdIELenForAssocRsp,     wfdFuncGenerateWfdIEForAssocRsp }, /* 221 */
427 #endif
428 #endif
429     { (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP),     NULL,     rlmRspGenerateExtCapIE   },      /* 127 */
430     { (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM),     NULL,    mqmGenerateWmmParamIE },         /* 221 */
431
432     { (0),         p2pFuncCalculateWSC_IELenForAssocRsp,      p2pFuncGenerateWSC_IEForAssocRsp }  /* 221 */
433
434 };
435 #endif
436
437 /*******************************************************************************
438 *                           P R I V A T E   D A T A
439 ********************************************************************************
440 */
441
442 /*******************************************************************************
443 *                                 M A C R O S
444 ********************************************************************************
445 */
446
447 /*******************************************************************************
448 *                   F U N C T I O N   D E C L A R A T I O N S
449 ********************************************************************************
450 */
451
452 /*******************************************************************************
453 *                              F U N C T I O N S
454 ********************************************************************************
455 */
456 /*----------------------------------------------------------------------------*/
457 /*!
458 * @brief This function is used to compose the Capability Info Field.
459 *
460 * @param[in] prStaRec               Pointer to the STA_RECORD_T
461 *
462 * @retval Capability Info Field
463 */
464 /*----------------------------------------------------------------------------*/
465 __KAL_INLINE__ UINT_16
466 assocBuildCapabilityInfo (
467     IN P_ADAPTER_T prAdapter,
468     IN P_STA_RECORD_T prStaRec
469     )
470 {
471     UINT_32 u4NonHTPhyType;
472     UINT_16 u2CapInfo;
473
474
475     ASSERT(prStaRec);
476
477
478     /* Set up our requested capabilities. */
479     u2CapInfo = CAP_INFO_ESS;
480     u2CapInfo |= CAP_CF_STA_NOT_POLLABLE;
481
482     if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) {
483         u2CapInfo |= CAP_INFO_PRIVACY;
484     }
485
486
487     /* 7.3.1.4 */
488     if (prStaRec->fgHasBasicPhyType) {
489         u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
490
491         if ( (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) &&
492             ( (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */
493              ((prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_AUTO) &&
494               (prStaRec->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)) ) ) {
495
496             /* Case I: Implemented == TRUE and Short Preamble Option Enable == TRUE.
497              * Case II: Implemented == TRUE and Short Preamble == AUTO (depends on
498              *          BSS_DESC_T's capability)
499              */
500             u2CapInfo |= CAP_INFO_SHORT_PREAMBLE;
501         }
502
503 #if CFG_SUPPORT_SPEC_MGMT   /*Add for DFS support*/
504         /* Support 802.11h */
505         if(prAdapter->fgEnable5GBand == TRUE) {
506             u2CapInfo |= CAP_INFO_SPEC_MGT;
507         }
508 #endif
509
510         if (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented &&
511             prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) {
512             u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME;
513         }
514     }
515
516     DBGLOG(SAA, LOUD, ("ASSOC REQ: Compose Capability = 0x%04x for Target BSS ["MACSTR"].\n",
517         u2CapInfo, MAC2STR(prStaRec->aucMacAddr)));
518
519
520     return u2CapInfo;
521
522 } /* end of assocBuildCapabilityInfo() */
523
524
525 /*----------------------------------------------------------------------------*/
526 /*!
527 * @brief This function is used to compose Common Information Elements for Association
528 *        Request Frame.
529 *
530 * @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
531 *
532 * @return (none)
533 */
534 /*----------------------------------------------------------------------------*/
535 __KAL_INLINE__ VOID
536 assocBuildReAssocReqFrameCommonIEs (
537     IN P_ADAPTER_T prAdapter,
538     IN P_MSDU_INFO_T prMsduInfo
539     )
540 {
541     P_CONNECTION_SETTINGS_T prConnSettings;
542     P_STA_RECORD_T prStaRec;
543     PUINT_8 pucBuffer;
544     UINT_16 u2SupportedRateSet;
545     UINT_8 aucAllSupportedRates[RATE_NUM] = {0};
546     UINT_8 ucAllSupportedRatesLen;
547     UINT_8 ucSupRatesLen;
548     UINT_8 ucExtSupRatesLen;
549
550     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
551     ASSERT(prMsduInfo);
552     ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
553
554     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
555     ASSERT(prStaRec);
556
557     if(!prStaRec) {
558         return;
559     }
560
561     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
562                           (UINT_32)prMsduInfo->u2FrameLength);
563     ASSERT(pucBuffer);
564
565     if (IS_STA_IN_AIS(prStaRec)) {
566
567         /* Fill the SSID element. */
568         SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
569
570         /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of
571          * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame.
572          */
573
574         COPY_SSID(SSID_IE(pucBuffer)->aucSSID,
575                   SSID_IE(pucBuffer)->ucLength,
576                   prConnSettings->aucSSID,
577                   prConnSettings->ucSSIDLen);
578
579         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
580         pucBuffer += IE_SIZE(pucBuffer);
581
582     }
583 #if CFG_ENABLE_WIFI_DIRECT
584     else if((prAdapter->fgIsP2PRegistered) &&
585         (IS_STA_IN_P2P(prStaRec))) {
586         pucBuffer = p2pBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo, pucBuffer);
587     }
588 #endif
589 #if CFG_ENABLE_BT_OVER_WIFI
590     else if (IS_STA_IN_BOW(prStaRec)) {
591
592         SSID_IE(pucBuffer)->ucId = ELEM_ID_SSID;
593
594         /* NOTE(Kevin): We copy the SSID from CONNECTION_SETTINGS for the case of
595          * Passive Scan and the target BSS didn't broadcast SSID on its Beacon Frame.
596          */
597
598         COPY_SSID(SSID_IE(pucBuffer)->aucSSID,
599                   SSID_IE(pucBuffer)->ucLength,
600                   prConnSettings->aucSSID,
601                   prConnSettings->ucSSIDLen);
602
603         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
604         pucBuffer += IE_SIZE(pucBuffer);
605     }
606 #endif
607
608     else {
609         /* TODO(Kevin): For other network */
610     }
611
612     /* NOTE(Kevin 2008/12/19): 16.3.6.3 MLME-ASSOCIATE.indication -
613      * SupportedRates - The set of data rates that are supported by the STA
614      * that is requesting association.
615      * Original(Portable Driver): Only send the Rates that we'll support.
616      * New: Send the Phy Rates if the result of following & operation == NULL.
617      */
618     //rateGetDataRatesFromRateSet((prBssDesc->u2OperationalRateSet &
619     //                             rPhyAttributes[prBssDesc->ePhyType].u2SupportedRateSet),
620
621     if (prStaRec->fgHasBasicPhyType) {
622         UINT_32 u4NonHTPhyType;
623
624
625         u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
626
627         u2SupportedRateSet = (prStaRec->u2OperationalRateSet &
628                               rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet);
629
630         ASSERT(u2SupportedRateSet);
631
632         if (!u2SupportedRateSet) {
633             u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
634         }
635
636         /* TODO(Kevin): For P2P, we shouldn't send support rate set which contains 11b rate */
637
638         rateGetDataRatesFromRateSet(u2SupportedRateSet,
639                                     0,
640                                     aucAllSupportedRates,
641                                     &ucAllSupportedRatesLen);
642
643         ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
644                          ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
645
646         ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
647
648
649         /* Fill the Supported Rates element. */
650         if (ucSupRatesLen) {
651             SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
652             SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
653             kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates,
654                        aucAllSupportedRates,
655                        ucSupRatesLen);
656
657             prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
658             pucBuffer += IE_SIZE(pucBuffer);
659         }
660
661
662         /* Fill the Extended Supported Rates element. */
663         if (ucExtSupRatesLen) {
664
665             EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
666             EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;
667
668             kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
669                        &aucAllSupportedRates[ucSupRatesLen],
670                        ucExtSupRatesLen);
671
672             prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
673             pucBuffer += IE_SIZE(pucBuffer);
674         }
675
676         /* 7.3.2.19 Supported Channels element*/
677 #if CFG_SUPPORT_DFS // Add for DFS support
678         if(prAdapter->fgEnable5GBand == TRUE) {
679             SUPPORTED_CHANNELS_IE(pucBuffer)->ucId = ELEM_ID_SUP_CHS;
680             SUPPORTED_CHANNELS_IE(pucBuffer)->ucLength = 8;
681
682             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[0] = 36;
683             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[1] = 4;
684             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[2] = 52;
685             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[3] = 4;
686 // Not China --- Start
687             //SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 100;
688             //SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 11;
689 // Not China --- End
690             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[4] = 149;
691             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[5] = 4;
692             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[6] = 165;
693             SUPPORTED_CHANNELS_IE(pucBuffer)->ucChannelNum[7] = 1;
694
695             prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
696             pucBuffer += IE_SIZE(pucBuffer);
697         }
698 #endif
699     }
700
701     return;
702 } /* end of assocBuildReAssocReqFrameCommonIEs() */
703
704
705 /*----------------------------------------------------------------------------*/
706 /*!
707 * @brief This function will compose the (Re)Association Request frame header and
708 *        its fixed fields
709 *
710 * @param[in] prStaRec               Pointer to the STA_RECORD_T
711 * @param[in] pucBuffer              Pointer to the frame buffer.
712 * @param[in] aucMACAddress          Given Our MAC Address.
713 * @param[in out] pu2PayloadLen      Return the length of the composed fixed fields
714 *
715 * @return (none)
716 */
717 /*----------------------------------------------------------------------------*/
718 __KAL_INLINE__ VOID
719 assocComposeReAssocReqFrameHeaderAndFF (
720     IN P_ADAPTER_T prAdapter,
721     IN P_STA_RECORD_T prStaRec,
722     IN PUINT_8 pucBuffer,
723     IN UINT_8 aucMACAddress[],
724     IN OUT PUINT_16 pu2PayloadLen
725     )
726 {
727     P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
728     BOOLEAN fgIsReAssoc;
729
730     UINT_16 u2FrameCtrl;
731     UINT_16 u2CapInfo;
732     UINT_16 u2ListenInterval;
733
734
735     ASSERT(prStaRec);
736     ASSERT(pucBuffer);
737     ASSERT(aucMACAddress);
738     ASSERT(pu2PayloadLen);
739
740     prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T)pucBuffer;
741     fgIsReAssoc = prStaRec->fgIsReAssoc;
742
743     //4 <1> Compose the frame header of the (Re)Association Request  frame.
744     /* Fill the Frame Control field. */
745     if (fgIsReAssoc) {
746         u2FrameCtrl = MAC_FRAME_REASSOC_REQ;
747     }
748     else {
749         u2FrameCtrl = MAC_FRAME_ASSOC_REQ;
750     }
751     WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl);
752
753     /* Fill the DA field with Target BSSID. */
754     COPY_MAC_ADDR(prAssocFrame->aucDestAddr, prStaRec->aucMacAddr);
755
756     /* Fill the SA field with our MAC Address. */
757     COPY_MAC_ADDR(prAssocFrame->aucSrcAddr, aucMACAddress);
758
759     /* Fill the BSSID field with Target BSSID. */
760     COPY_MAC_ADDR(prAssocFrame->aucBSSID, prStaRec->aucMacAddr);
761
762     /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
763     prAssocFrame->u2SeqCtrl = 0;
764
765
766     //4 <2> Compose the frame body's common fixed field part of the (Re)Association Request  frame.
767     u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
768
769     /* Fill the Capability Information field. */
770     WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo);
771
772
773     /* Calculate the listen interval for the maximum power mode. Currently, we
774        set it to the value 2 times DTIM period. */
775     if (prStaRec->ucDTIMPeriod) {
776         u2ListenInterval = prStaRec->ucDTIMPeriod * DEFAULT_LISTEN_INTERVAL_BY_DTIM_PERIOD;
777     }
778     else {
779         DBGLOG(SAA, TRACE, ("Use default listen interval\n"));
780         u2ListenInterval = DEFAULT_LISTEN_INTERVAL;
781     }
782     prStaRec->u2ListenInterval = u2ListenInterval;
783
784     /* Fill the Listen Interval field. */
785     WLAN_SET_FIELD_16(&prAssocFrame->u2ListenInterval, u2ListenInterval);
786
787
788     //4 <3> Compose the Current AP Address field for ReAssociation Request  frame.
789     /* Fill the Current AP Address field. */
790     if (prStaRec->fgIsReAssoc) {
791         if (IS_STA_IN_AIS(prStaRec)) {
792
793             P_AIS_BSS_INFO_T prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
794             P_WLAN_REASSOC_REQ_FRAME_T prReAssocFrame =
795                 (P_WLAN_REASSOC_REQ_FRAME_T)prAssocFrame;
796
797             COPY_MAC_ADDR(prReAssocFrame->aucCurrentAPAddr, prAisBssInfo->aucBSSID);
798         }
799         else {
800             ASSERT(0); /* We don't support ReAssociation for other network */
801         }
802
803         *pu2PayloadLen = (CAP_INFO_FIELD_LEN +
804                          LISTEN_INTERVAL_FIELD_LEN +
805                          CURR_AP_ADDR_FIELD_LEN);
806     }
807     else {
808         *pu2PayloadLen = (CAP_INFO_FIELD_LEN +
809                          LISTEN_INTERVAL_FIELD_LEN);
810     }
811
812     return;
813 } /* end of assocComposeReAssocReqFrame() */
814
815
816 /*----------------------------------------------------------------------------*/
817 /*!
818 * @brief This function will send the (Re)Association Request frame
819 *
820 * @param[in] prStaRec           Pointer to the STA_RECORD_T
821 *
822 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
823 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
824 */
825 /*----------------------------------------------------------------------------*/
826 WLAN_STATUS
827 assocSendReAssocReqFrame (
828     IN P_ADAPTER_T prAdapter,
829     IN P_STA_RECORD_T prStaRec
830     )
831 {
832     P_MSDU_INFO_T prMsduInfo;
833     P_BSS_INFO_T prBssInfo;
834
835     UINT_16 u2PayloadLen;
836     UINT_16 u2EstimatedFrameLen;
837     UINT_16 u2EstimatedExtraIELen;
838     BOOLEAN fgIsReAssoc;
839     UINT_32 i;
840
841
842     ASSERT(prStaRec);
843
844     //4 <1> Allocate a PKT_INFO_T for Authentication Frame
845     fgIsReAssoc = prStaRec->fgIsReAssoc;
846
847     /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */
848     if (fgIsReAssoc) {
849         u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + \
850                               WLAN_MAC_MGMT_HEADER_LEN + \
851                               CAP_INFO_FIELD_LEN + \
852                               LISTEN_INTERVAL_FIELD_LEN + \
853                               CURR_AP_ADDR_FIELD_LEN + \
854                               (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + \
855                               (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + \
856                               (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
857     }
858     else {
859         u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + \
860                               WLAN_MAC_MGMT_HEADER_LEN + \
861                               CAP_INFO_FIELD_LEN + \
862                               LISTEN_INTERVAL_FIELD_LEN + \
863                               (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + \
864                               (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + \
865                               (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
866     }
867
868     /* + Extra IE Length */
869     u2EstimatedExtraIELen = 0;
870
871 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT
872     if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
873         if ((prAdapter->fgIsP2PRegistered)) {
874             u2EstimatedExtraIELen = p2pCalculate_IEForAssocReq(prAdapter,
875                                                                     prStaRec->ucNetTypeIndex,
876                                                                     prStaRec);
877         }
878         else {
879             DBGLOG(P2P, TRACE, ("Function Linker Lost.\n"));
880             ASSERT(FALSE);
881         }
882     }
883     else {
884         for (i = 0; i < sizeof(txAssocReqIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
885             if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) {
886                 u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen;
887             }
888             else {
889                 u2EstimatedExtraIELen += (UINT_16)txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter,
890                                                                                 prStaRec->ucNetTypeIndex,
891                                                                                 prStaRec);
892             }
893         }
894     }
895 #else
896     for (i = 0; i < sizeof(txAssocReqIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
897         if (txAssocReqIETable[i].u2EstimatedFixedIELen != 0) {
898             u2EstimatedExtraIELen += txAssocReqIETable[i].u2EstimatedFixedIELen;
899         }
900         else {
901             u2EstimatedExtraIELen += (UINT_16)txAssocReqIETable[i].pfnCalculateVariableIELen(prAdapter,
902                                                                             prStaRec->ucNetTypeIndex,
903                                                                             prStaRec);
904         }
905     }
906 #endif
907
908     u2EstimatedFrameLen += u2EstimatedExtraIELen;
909
910     /* Allocate a MSDU_INFO_T */
911     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
912         DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending (Re)Assoc Request.\n"));
913         return WLAN_STATUS_RESOURCES;
914     }
915
916     //4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T.
917     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
918     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
919
920
921     /* Compose Header and Fixed Field */
922     assocComposeReAssocReqFrameHeaderAndFF(prAdapter,
923             prStaRec,
924             (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
925             prBssInfo->aucOwnMacAddr,
926             &u2PayloadLen);
927
928     //4 <3> Update information of MSDU_INFO_T
929     prMsduInfo->eSrc = TX_PACKET_MGMT;
930     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
931     prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
932     prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
933     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
934     prMsduInfo->fgIs802_1x = FALSE;
935     prMsduInfo->fgIs802_11 = TRUE;
936     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
937     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
938     prMsduInfo->pfTxDoneHandler = saaFsmRunEventTxDone;
939     prMsduInfo->fgIsBasicRate = TRUE;
940
941     //4 <4> Compose the frame body's IEs of the (Re)Association Request  frame.
942     assocBuildReAssocReqFrameCommonIEs(prAdapter, prMsduInfo);
943
944
945     //4 <5> Compose IEs in MSDU_INFO_T
946 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211 && CFG_ENABLE_WIFI_DIRECT
947     if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
948         if ((prAdapter->fgIsP2PRegistered)) {
949             p2pGenerate_IEForAssocReq(prAdapter, prMsduInfo);
950         }
951         else {
952             DBGLOG(P2P, TRACE, ("Function Linker Lost.\n"));
953             ASSERT(FALSE);
954         }
955     }
956     else {
957         /* Append IE */
958         for (i = 0; i < sizeof(txAssocReqIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
959             if (txAssocReqIETable[i].pfnAppendIE) {
960                 txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
961             }
962         }
963     }
964 #else
965     /* Append IE */
966     for (i = 0; i < sizeof(txAssocReqIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
967         if (txAssocReqIETable[i].pfnAppendIE) {
968             txAssocReqIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
969         }
970     }
971 #endif
972
973     //4 <6> Update the (Re)association request information
974     if (IS_STA_IN_AIS(prStaRec)) {
975         P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
976
977         prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
978
979 #if CFG_RSN_MIGRATION
980         kalUpdateReAssocReqInfo(prAdapter->prGlueInfo,
981                                 (PUINT_8)&prAssocFrame->u2CapInfo,
982                                 prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo),
983                                 fgIsReAssoc);
984 #endif
985     }
986
987 #if CFG_ENABLE_WIFI_DIRECT
988     if ((prAdapter->fgIsP2PRegistered) && (IS_STA_IN_P2P(prStaRec))) {
989         P_WLAN_ASSOC_REQ_FRAME_T prAssocFrame;
990
991         prAssocFrame = (P_WLAN_ASSOC_REQ_FRAME_T)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
992
993
994         kalP2PUpdateAssocInfo(
995             prAdapter->prGlueInfo,
996             (PUINT_8)&prAssocFrame->u2CapInfo,
997             prMsduInfo->u2FrameLength - offsetof(WLAN_ASSOC_REQ_FRAME_T, u2CapInfo),
998             fgIsReAssoc);
999     }
1000 #endif
1001
1002     /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
1003
1004     //4 <6> Enqueue the frame to send this (Re)Association request frame.
1005     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
1006
1007     return WLAN_STATUS_SUCCESS;
1008 } /* end of assocSendReAssocReqFrame() */
1009
1010
1011 /*----------------------------------------------------------------------------*/
1012 /*!
1013 * @brief This function will strictly check the TX (Re)Association Request frame for
1014 *        SAA event handling.
1015 *
1016 * @param[in] prMsduInfo         Pointer of MSDU_INFO_T
1017 *
1018 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1019 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1020 */
1021 /*----------------------------------------------------------------------------*/
1022 WLAN_STATUS
1023 assocCheckTxReAssocReqFrame (
1024     IN P_ADAPTER_T      prAdapter,
1025     IN P_MSDU_INFO_T    prMsduInfo
1026     )
1027 {
1028     P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
1029     P_STA_RECORD_T prStaRec;
1030     UINT_16 u2TxFrameCtrl;
1031
1032
1033     ASSERT(prMsduInfo);
1034     ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
1035
1036     prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T)(prMsduInfo->prPacket);
1037     ASSERT(prAssocReqFrame);
1038
1039     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1040     ASSERT(prStaRec);
1041
1042     if(!prStaRec) {
1043         return WLAN_STATUS_INVALID_PACKET;
1044     }
1045
1046     //WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2TxFrameCtrl)
1047     u2TxFrameCtrl = prAssocReqFrame->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1048     u2TxFrameCtrl &= MASK_FRAME_TYPE;
1049     if (prStaRec->fgIsReAssoc) {
1050         if (u2TxFrameCtrl != MAC_FRAME_REASSOC_REQ) {
1051             return WLAN_STATUS_FAILURE;
1052         }
1053     }
1054     else {
1055         if (u2TxFrameCtrl != MAC_FRAME_ASSOC_REQ) {
1056             return WLAN_STATUS_FAILURE;
1057         }
1058     }
1059
1060     return WLAN_STATUS_SUCCESS;
1061
1062 } /* end of assocCheckTxReAssocReqFrame() */
1063
1064
1065 /*----------------------------------------------------------------------------*/
1066 /*!
1067 * @brief This function will strictly check the TX (Re)Association Response frame for
1068 *        AAA event handling.
1069 *
1070 * @param[in] prMsduInfo         Pointer of MSDU_INFO_T
1071 *
1072 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1073 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1074 */
1075 /*----------------------------------------------------------------------------*/
1076 WLAN_STATUS
1077 assocCheckTxReAssocRespFrame (
1078     IN P_ADAPTER_T   prAdapter,
1079     IN P_MSDU_INFO_T prMsduInfo
1080     )
1081 {
1082     P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
1083     P_STA_RECORD_T prStaRec;
1084     UINT_16 u2TxFrameCtrl;
1085
1086
1087     ASSERT(prMsduInfo);
1088     ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
1089
1090     prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T)(prMsduInfo->prPacket);
1091     ASSERT(prAssocRspFrame);
1092
1093     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1094     ASSERT(prStaRec);
1095
1096     if(!prStaRec) {
1097         return WLAN_STATUS_INVALID_PACKET;
1098     }
1099
1100     //WLAN_GET_FIELD_16(&prAssocFrame->u2FrameCtrl, &u2TxFrameCtrl)
1101     u2TxFrameCtrl = prAssocRspFrame->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1102     u2TxFrameCtrl &= MASK_FRAME_TYPE;
1103     if (prStaRec->fgIsReAssoc) {
1104         if (u2TxFrameCtrl != MAC_FRAME_REASSOC_RSP) {
1105             return WLAN_STATUS_FAILURE;
1106         }
1107     }
1108     else {
1109         if (u2TxFrameCtrl != MAC_FRAME_ASSOC_RSP) {
1110             return WLAN_STATUS_FAILURE;
1111         }
1112     }
1113
1114     return WLAN_STATUS_SUCCESS;
1115
1116 } /* end of assocCheckTxReAssocRespFrame() */
1117
1118
1119 /*----------------------------------------------------------------------------*/
1120 /*!
1121 * @brief This function will validate the incoming (Re)Association Frame and take out
1122 *        the status code.
1123 *
1124 * @param[in] prSwRfb                Pointer to SW RFB data structure.
1125 * @param[out] pu2StatusCode         Pointer to store the Status Code from Authentication.
1126 *
1127 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1128 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1129 */
1130 /*----------------------------------------------------------------------------*/
1131 WLAN_STATUS
1132 assocCheckRxReAssocRspFrameStatus (
1133     IN P_ADAPTER_T  prAdapter,
1134     IN P_SW_RFB_T   prSwRfb,
1135     OUT PUINT_16    pu2StatusCode
1136     )
1137 {
1138     P_STA_RECORD_T prStaRec;
1139     P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
1140     UINT_16 u2RxFrameCtrl;
1141     UINT_16 u2RxCapInfo;
1142     UINT_16 u2RxStatusCode;
1143     UINT_16 u2RxAssocId;
1144
1145
1146     ASSERT(prSwRfb);
1147     ASSERT(pu2StatusCode);
1148
1149     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < (CAP_INFO_FIELD_LEN +
1150                                     STATUS_CODE_FIELD_LEN +
1151                                     AID_FIELD_LEN)) {
1152         ASSERT(0);
1153         return WLAN_STATUS_FAILURE;
1154     }
1155
1156     DBGLOG(SAA, LOUD, ("prSwRfb->u2PayloadLength = %d\n", prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen));
1157
1158     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1159     ASSERT(prStaRec);
1160
1161     if(!prStaRec) {
1162         return WLAN_STATUS_INVALID_PACKET;
1163     }
1164
1165     //4 <1> locate the (Re)Assocation Resp Frame.
1166     prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader;
1167
1168     //4 <2> Parse the Header of (Re)Assocation Resp Frame.
1169     //WLAN_GET_FIELD_16(&prAssocRspFrame->u2FrameCtrl, &u2RxFrameCtrl);
1170     u2RxFrameCtrl = prAssocRspFrame->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1171     u2RxFrameCtrl &= MASK_FRAME_TYPE;
1172     if (prStaRec->fgIsReAssoc) {
1173         if (u2RxFrameCtrl != MAC_FRAME_REASSOC_RSP) {
1174             return WLAN_STATUS_FAILURE;
1175         }
1176     }
1177     else {
1178         if (u2RxFrameCtrl != MAC_FRAME_ASSOC_RSP) {
1179             return WLAN_STATUS_FAILURE;
1180         }
1181     }
1182
1183     //4 <3> Parse the Fixed Fields of (Re)Assocation Resp Frame Body.
1184     //WLAN_GET_FIELD_16(&prAssocRspFrame->u2CapInfo, &u2RxCapInfo);
1185     u2RxCapInfo = prAssocRspFrame->u2CapInfo; // NOTE(Kevin): Optimized for ARM
1186
1187     //WLAN_GET_FIELD_16(&prAssocRspFrame->u2StatusCode, &u2RxStatusCode);
1188     u2RxStatusCode = prAssocRspFrame->u2StatusCode; // NOTE(Kevin): Optimized for ARM
1189
1190     //4 <4> Check CAP_INFO
1191     /* NOTE(Kevin): CM suggest to add MGMT workaround for those APs didn't check
1192      * the CAP Privacy Bit to overcome a corner case that the Privacy Bit
1193      * of our SCAN result didn't consist with AP's Association Resp.
1194      */
1195     if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
1196 #if CFG_SUPPORT_WAPI
1197         if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
1198             /* WAPI AP allow the customer use WZC to join mode, the privacy bit is 0 */
1199             /* even at WAI & WAPI_PSK mode, but the assoc respose set the privacy bit set 1 */
1200             DBGLOG(SEC, TRACE, ("Workaround the WAPI AP allow the customer to use WZC to join\n"));
1201         }
1202         else
1203 #endif
1204 #if CFG_ENABLE_WIFI_DIRECT
1205         if (prAdapter->fgIsP2PRegistered && 1) {
1206         /* Todo:: Fixed this */
1207         }
1208         else
1209 #endif
1210         {
1211         }
1212
1213 #if CFG_STRICT_CHECK_CAPINFO_PRIVACY
1214         if ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) {
1215             u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED;
1216         }
1217 #endif
1218     }
1219
1220     if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
1221 #if CFG_RSN_MIGRATION
1222         /* Update the information in the structure used to query and set
1223            OID_802_11_ASSOCIATION_INFORMATION. */
1224         kalUpdateReAssocRspInfo(prAdapter->prGlueInfo,
1225                                (PUINT_8)&prAssocRspFrame->u2CapInfo,
1226                                (UINT_32)(prSwRfb->u2PacketLen));
1227 #endif
1228     }
1229
1230     //4 <5> Update CAP_INFO and ASSOC_ID
1231     if (u2RxStatusCode == STATUS_CODE_SUCCESSFUL) {
1232         prStaRec->u2CapInfo = u2RxCapInfo;
1233
1234         //WLAN_GET_FIELD_16(&prAssocRspFrame->u2AssocId, &u2RxAssocId);
1235         u2RxAssocId = prAssocRspFrame->u2AssocId; // NOTE(Kevin): Optimized for ARM
1236
1237         /*  20110715 Workaround for Kingnet 710 AP (Realtek 8186)
1238                 *   This AP raises the bit 6&7 not bit 14&15 in AID field.
1239                 *   It cause wrong AID assignment.
1240                 *   For AID = 2
1241                 *     Normal case: 0xC002(1100 0000 0000 0010) => 2
1242                 *     Kingnet 710:  0x00C2(0000 0000 1100 0010) => 194
1243                 *     workaround: mask bit 6&7 for this AP
1244                 */
1245         if((u2RxAssocId & BIT(6)) &&
1246            (u2RxAssocId & BIT(7)) &&
1247            !(u2RxAssocId & BITS(8, 15))) {
1248             prStaRec->u2AssocId = u2RxAssocId & ~BITS(6,7);
1249         } else {
1250             prStaRec->u2AssocId = u2RxAssocId & ~AID_MSB;
1251 #if CFG_SUPPORT_802_11W
1252             if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
1253                 P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
1254
1255                 prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1256                 ASSERT(prBssSpecInfo);
1257
1258                 prBssSpecInfo->ucSaQueryTimedOut = 0;
1259             }
1260 #endif
1261         }
1262     }
1263
1264 #if CFG_SUPPORT_802_11W
1265     if (u2RxStatusCode == STATUS_CODE_AUTH_ALGORITHM_NOT_SUPPORTED){
1266         DBGLOG(SAA, INFO, ("AP rejected due the authentication algorithm not support\n"));
1267     }
1268     else if (u2RxStatusCode == STATUS_CODE_ASSOC_REJECTED_TEMPORARILY) {
1269         PUINT_8 pucIE, pucTime;
1270         UINT_16 u2IELength;
1271         UINT_16 u2Offset = 0;
1272
1273         u2IELength = prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen;
1274         pucIE = (PUINT_8)((UINT_32)prSwRfb->pvHeader + prSwRfb->u2HeaderLen);
1275
1276         IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1277             if (ELEM_ID_TIMEOUT_INTERVAL == IE_ID(pucIE) && IE_LEN(pucIE) == 5) {
1278                 pucTime = ((P_IE_HDR_T)pucIE)->aucInfo;
1279                 if (pucTime[0] == ACTION_SA_TIMEOUT_ASSOC_COMEBACK) {
1280                     UINT_32 tu;
1281                     WLAN_GET_FIELD_32(pucTime + 1, &tu);
1282                     DBGLOG(SAA, INFO, ("AP rejected association temporarily; comeback duration %u TU "
1283                            "(%u ms)\n", tu, TU_TO_MSEC(tu)));
1284                     if (tu > TX_ASSOCIATION_RETRY_TIMEOUT_TU) {
1285                         DBGLOG(SAA, INFO, ("Update timer based on comeback duration\n"));
1286                         //ieee80211_reschedule_timer(wpa_s, ms);
1287                     }
1288                 }
1289                 break;
1290             }
1291         } /* end of IE_FOR_EACH */
1292     }
1293 #endif
1294     *pu2StatusCode = u2RxStatusCode;
1295
1296     return WLAN_STATUS_SUCCESS;
1297
1298 } /* end of assocCheckRxReAssocRspFrameStatus() */
1299
1300
1301 /*----------------------------------------------------------------------------*/
1302 /*!
1303 * \brief This function will compose the Disassociation frame
1304 *
1305 * @param[in] prStaRec               Pointer to the STA_RECORD_T
1306 * @param[in] pucBuffer              Pointer to the frame buffer.
1307 * @param[in] aucMACAddress     Given Our MAC Address.
1308 * @param[in] u2ReasonCode      The reason code of disassociation
1309 *
1310 * \return (none)
1311 */
1312 /*----------------------------------------------------------------------------*/
1313 __KAL_INLINE__ VOID
1314 assocComposeDisassocFrame (
1315     IN P_STA_RECORD_T   prStaRec,
1316     IN PUINT_8          pucBuffer,
1317     IN UINT_8           aucMACAddress[],
1318     IN UINT_16          u2ReasonCode
1319     )
1320 {
1321     P_WLAN_DISASSOC_FRAME_T prDisAssocFrame;
1322     UINT_16 u2FrameCtrl;
1323
1324     ASSERT(pucBuffer);
1325     ASSERT(pucBuffer);
1326     ASSERT(aucMACAddress);
1327
1328     prDisAssocFrame = (P_WLAN_DISASSOC_FRAME_T)pucBuffer;
1329
1330     //4 <1> Compose the frame header of the DisAssociation  frame.
1331     /* Fill the Frame Control field. */
1332     u2FrameCtrl = MAC_FRAME_DISASSOC;
1333
1334     WLAN_SET_FIELD_16(&prDisAssocFrame->u2FrameCtrl, u2FrameCtrl);
1335
1336     /* Fill the DA field with Target BSSID. */
1337     COPY_MAC_ADDR(prDisAssocFrame->aucDestAddr, prStaRec->aucMacAddr);
1338
1339     /* Fill the SA field with our MAC Address. */
1340     COPY_MAC_ADDR(prDisAssocFrame->aucSrcAddr, aucMACAddress);
1341
1342     /* Fill the BSSID field with Target BSSID. */
1343     COPY_MAC_ADDR(prDisAssocFrame->aucBSSID, prStaRec->aucMacAddr);
1344
1345     /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
1346     prDisAssocFrame->u2SeqCtrl = 0;
1347
1348     //4 <2> Compose the frame body's fixed field part of the Disassociation frame.
1349     /* Fill the Reason Code field. */
1350     WLAN_SET_FIELD_16(&prDisAssocFrame->u2ReasonCode, u2ReasonCode);
1351
1352     return;
1353 } /* end of assocComposeDisassocFrame() */
1354
1355
1356 /*----------------------------------------------------------------------------*/
1357 /*!
1358 * @brief This function will send the Disassociation frame
1359 *
1360 * @param[in] prStaRec           Pointer to the STA_RECORD_T
1361 * @param[in] u2ReasonCode  The reason code of disassociation
1362 *
1363 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
1364 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
1365 */
1366 /*----------------------------------------------------------------------------*/
1367 WLAN_STATUS
1368 assocSendDisAssocFrame (
1369     IN P_ADAPTER_T    prAdapter,
1370     IN P_STA_RECORD_T prStaRec,
1371     IN UINT_16        u2ReasonCode
1372     )
1373 {
1374     PUINT_8 pucMacAddress;
1375     P_MSDU_INFO_T prMsduInfo;
1376     UINT_16 u2PayloadLen;
1377     UINT_16 u2EstimatedFrameLen;
1378     //UINT_32 u4Status = WLAN_STATUS_SUCCESS;
1379
1380
1381     ASSERT(prStaRec);
1382
1383     //4 <1> Allocate a PKT_INFO_T for Disassociation Frame
1384     /* Init with MGMT Header Length + Length of Fixed Fields + IE Length */
1385     u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + \
1386                           WLAN_MAC_MGMT_HEADER_LEN + \
1387                           REASON_CODE_FIELD_LEN;
1388
1389     /* Allocate a MSDU_INFO_T */
1390     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
1391         DBGLOG(SAA, WARN, ("No PKT_INFO_T for sending DisAssoc.\n"));
1392         return WLAN_STATUS_RESOURCES;
1393     }
1394
1395     //4 <2> Compose Disassociation  frame header and fixed fields in MSDU_INfO_T.
1396     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1397
1398     pucMacAddress = prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex].aucOwnMacAddr;
1399
1400     /* Compose Header and Fixed Field */
1401     assocComposeDisassocFrame(prStaRec,
1402                               (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
1403                               pucMacAddress,
1404                               u2ReasonCode);
1405
1406 #if CFG_SUPPORT_802_11W
1407     if (rsnCheckBipKeyInstalled(prAdapter, prStaRec)) {
1408         P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
1409
1410         prDisassocFrame = (P_WLAN_DEAUTH_FRAME_T)(PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
1411
1412         prDisassocFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
1413         DBGLOG(TX, WARN, ("assocSendDisAssocFrame with protection\n"));
1414     }
1415 #endif
1416
1417     u2PayloadLen = REASON_CODE_FIELD_LEN;
1418
1419     //4 <3> Update information of MSDU_INFO_T
1420     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
1421
1422     prMsduInfo->eSrc = TX_PACKET_MGMT;
1423     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
1424     prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
1425     prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
1426     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
1427     prMsduInfo->fgIs802_1x = FALSE;
1428     prMsduInfo->fgIs802_11 = TRUE;
1429     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
1430     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
1431     prMsduInfo->pfTxDoneHandler = NULL;
1432     prMsduInfo->fgIsBasicRate = TRUE;
1433
1434     //4 <4> Enqueue the frame to send this (Re)Association request frame.
1435     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
1436
1437     return WLAN_STATUS_SUCCESS;
1438 } /* end of assocSendDisAssocFrame() */
1439
1440
1441 /*----------------------------------------------------------------------------*/
1442 /*!
1443 * @brief This function will parse and process the incoming Disassociation frame
1444 *        if the given BSSID is matched.
1445 *
1446 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1447 * @param[in] aucBSSID           Given BSSID
1448 * @param[out] pu2ReasonCode     Pointer to store the Reason Code from Deauthentication.
1449 *
1450 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1451 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1452 */
1453 /*----------------------------------------------------------------------------*/
1454 WLAN_STATUS
1455 assocProcessRxDisassocFrame (
1456     IN P_ADAPTER_T  prAdapter,
1457     IN P_SW_RFB_T   prSwRfb,
1458     IN UINT_8       aucBSSID[],
1459     OUT PUINT_16    pu2ReasonCode
1460     )
1461 {
1462     P_WLAN_DISASSOC_FRAME_T prDisassocFrame;
1463     UINT_16 u2RxReasonCode;
1464
1465
1466     ASSERT(prSwRfb);
1467     ASSERT(aucBSSID);
1468     ASSERT(pu2ReasonCode);
1469
1470     //4 <1> locate the Disassociation Frame.
1471     prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader;
1472
1473     //4 <2> Parse the Header of Disassociation Frame.
1474     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) < REASON_CODE_FIELD_LEN) {
1475         ASSERT(0);
1476         return WLAN_STATUS_FAILURE;
1477     }
1478
1479     /* Check if this Disassoc Frame is coming from Target BSSID */
1480     if (UNEQUAL_MAC_ADDR(prDisassocFrame->aucBSSID, aucBSSID)) {
1481         DBGLOG(SAA, LOUD, ("Ignore Disassoc Frame from other BSS ["MACSTR"]\n",
1482             MAC2STR(prDisassocFrame->aucSrcAddr)));
1483         return WLAN_STATUS_FAILURE;
1484     }
1485
1486     //4 <3> Parse the Fixed Fields of Deauthentication Frame Body.
1487     WLAN_GET_FIELD_16(&prDisassocFrame->u2ReasonCode, &u2RxReasonCode);
1488     *pu2ReasonCode = u2RxReasonCode;
1489
1490     return WLAN_STATUS_SUCCESS;
1491
1492 } /* end of assocProcessRxDisassocFrame() */
1493
1494
1495 #if CFG_SUPPORT_AAA
1496 /*----------------------------------------------------------------------------*/
1497 /*!
1498 * @brief This function will parse and process the incoming Association Req frame
1499 *        and return a Status Code.
1500 *
1501 * @param[in] prAdapter          Pointer to the Adapter structure.
1502 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1503 * @param[out] pu2StatusCode     Pointer to store the Status Code for carried in Association Response.
1504 *
1505 * @retval WLAN_STATUS_FAILURE   This is not the frame we should handle at current state.
1506 * @retval WLAN_STATUS_SUCCESS   This is the frame we should handle.
1507 */
1508 /*----------------------------------------------------------------------------*/
1509 WLAN_STATUS
1510 assocProcessRxAssocReqFrame (
1511     IN P_ADAPTER_T  prAdapter,
1512     IN P_SW_RFB_T   prSwRfb,
1513     OUT PUINT_16    pu2StatusCode
1514     )
1515 {
1516     P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
1517     P_STA_RECORD_T prStaRec;
1518     P_BSS_INFO_T prBssInfo;
1519     P_IE_SSID_T prIeSsid = (P_IE_SSID_T)NULL;
1520     P_RSN_INFO_ELEM_T prIeRsn = (P_RSN_INFO_ELEM_T)NULL;
1521     P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T)NULL;
1522     P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T)NULL;
1523     PUINT_8 pucIE, pucIEStart;
1524     UINT_16 u2IELength;
1525     UINT_16 u2Offset = 0;
1526     UINT_16 u2StatusCode = STATUS_CODE_SUCCESSFUL;
1527     UINT_16 u2RxFrameCtrl;
1528     UINT_16 u2BSSBasicRateSet;
1529     BOOLEAN fgIsUnknownBssBasicRate;
1530     UINT_32 i;
1531
1532
1533     ASSERT(prAdapter);
1534     ASSERT(prSwRfb);
1535     ASSERT(pu2StatusCode);
1536
1537     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1538
1539     if (prStaRec == NULL) {
1540         return WLAN_STATUS_FAILURE;
1541     }
1542
1543     //4 <1> locate the Association Req Frame.
1544     prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
1545
1546     //4 <2> Parse the Header of Association Req Frame.
1547     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
1548             (CAP_INFO_FIELD_LEN + LISTEN_INTERVAL_FIELD_LEN)) {
1549         ASSERT(0);
1550         return WLAN_STATUS_FAILURE;
1551     }
1552
1553     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
1554
1555     /* Check if this Disassoc Frame is coming from Target BSSID */
1556     if (UNEQUAL_MAC_ADDR(prAssocReqFrame->aucBSSID, prBssInfo->aucBSSID)) {
1557         return WLAN_STATUS_FAILURE; /* Just Ignore this MMPDU */
1558     }
1559
1560     //WLAN_GET_FIELD_16(&prAssocReqFrame->u2FrameCtrl, &u2RxFrameCtrl);
1561     u2RxFrameCtrl = prAssocReqFrame->u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1562     u2RxFrameCtrl &= MASK_FRAME_TYPE;
1563     if (MAC_FRAME_REASSOC_REQ == u2RxFrameCtrl) {
1564         prStaRec->fgIsReAssoc = TRUE;
1565
1566         u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1567             (UINT_16)(OFFSET_OF(WLAN_REASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN);
1568
1569         pucIEStart = pucIE = ((P_WLAN_REASSOC_REQ_FRAME_T)(prSwRfb->pvHeader))->aucInfoElem;
1570     }
1571     else {
1572         prStaRec->fgIsReAssoc = FALSE;
1573
1574         u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1575             (UINT_16)(OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN);
1576
1577         pucIEStart = pucIE = prAssocReqFrame->aucInfoElem;
1578     }
1579
1580
1581     //4 <3> Parse the Fixed Fields of Assoc Req Frame Body.
1582     prStaRec->u2CapInfo = prAssocReqFrame->u2CapInfo;
1583
1584 #if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
1585     if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1586         if (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) &&
1587                 !kalP2PGetCipher(prAdapter->prGlueInfo))) {
1588             u2StatusCode = STATUS_CODE_CAP_NOT_SUPPORTED;
1589             DBGLOG(RSN, TRACE, ("STA Assoc req privacy bit check fail\n"));
1590             return WLAN_STATUS_SUCCESS;
1591         }
1592     }
1593 #endif
1594
1595     prStaRec->u2ListenInterval = prAssocReqFrame->u2ListenInterval;
1596     prStaRec->ucPhyTypeSet = 0;
1597
1598     /* Might be legacy client or p2p gc. */
1599     prStaRec->eStaType = STA_TYPE_LEGACY_CLIENT;
1600
1601     //4 <4> Parse the IE of Assoc Req Frame Body.
1602     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1603         switch (IE_ID(pucIE)) {
1604         case ELEM_ID_SSID:
1605             if ((!prIeSsid) && /* NOTE(Kevin): Get SSID once */
1606                 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1607                 prIeSsid = (P_IE_SSID_T)pucIE;
1608             }
1609             break;
1610
1611         case ELEM_ID_SUP_RATES:
1612             if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1613                 prIeSupportedRate = SUP_RATES_IE(pucIE);
1614             }
1615             break;
1616
1617         case ELEM_ID_EXTENDED_SUP_RATES:
1618             if (!prIeExtSupportedRate)
1619                 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1620             break;
1621         case ELEM_ID_HT_CAP:
1622             prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
1623                         kalMemCopy(&prStaRec->u2HtCapInfo, &(HT_CAP_IE(pucIE)->u2HtCapInfo), 2);
1624             break;
1625         case ELEM_ID_RSN:
1626             #if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
1627             if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1628                 prIeRsn = RSN_IE(pucIE);
1629                 rsnParserCheckForRSNCCMPPSK(prAdapter, prIeRsn, &u2StatusCode);
1630                 if (u2StatusCode != STATUS_CODE_SUCCESSFUL) {
1631                     *pu2StatusCode = u2StatusCode;
1632                     return WLAN_STATUS_SUCCESS;
1633                 }
1634             }
1635             #endif
1636             break;
1637         case ELEM_ID_VENDOR:
1638             #if CFG_ENABLE_WIFI_DIRECT
1639             {
1640                 if ((prAdapter->fgIsP2PRegistered)) {
1641                     UINT_8 ucOuiType = 0;
1642
1643                     p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType);
1644
1645                     if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1646                         DBGLOG(P2P, TRACE, ("Target Client is a P2P group client\n"));
1647                         prStaRec->eStaType = STA_TYPE_P2P_GC;
1648                     }
1649                 }
1650             }
1651             #endif
1652             break;
1653         default:
1654             for (i = 0; i < (sizeof(rxAssocReqIETable) / sizeof(VERIFY_IE_ENTRY_T)); i++) {
1655
1656                 if ((IE_ID(pucIE)) == rxAssocReqIETable[i].ucElemID) {
1657                     rxAssocReqIETable[i].pfnVarifyIE(prAdapter, prSwRfb, (P_IE_HDR_T)pucIE, &u2StatusCode);
1658
1659                     if (u2StatusCode != STATUS_CODE_SUCCESSFUL) {
1660                         *pu2StatusCode = u2StatusCode;
1661                         return WLAN_STATUS_SUCCESS;
1662                     }
1663                 }
1664             }
1665
1666             break;
1667         }
1668     } /* end of IE_FOR_EACH */
1669
1670     // parsing for WMM related information (2010/12/21)
1671     mqmProcessAssocReq(
1672         prAdapter,
1673         prSwRfb,
1674         pucIEStart,
1675         u2IELength);
1676
1677     do {
1678         if (prIeSsid) {
1679             if (UNEQUAL_SSID(prBssInfo->aucSSID, prBssInfo->ucSSIDLen,
1680                              prIeSsid->aucSSID, prIeSsid->ucLength)) {
1681
1682                 u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE;
1683                 break;
1684             }
1685         }
1686         else {
1687             u2StatusCode = STATUS_CODE_UNSPECIFIED_FAILURE;
1688             break;
1689         }
1690
1691         prStaRec->u2OperationalRateSet = 0;
1692         prStaRec->u2BSSBasicRateSet = 0;
1693
1694         if (prIeSupportedRate || prIeExtSupportedRate) {
1695             rateGetRateSetFromIEs(prIeSupportedRate,
1696                                   prIeExtSupportedRate,
1697                                   &prStaRec->u2OperationalRateSet,
1698                                   &u2BSSBasicRateSet, /* Ignore any Basic Bit */
1699                                   &fgIsUnknownBssBasicRate);
1700
1701             if ((prBssInfo->u2BSSBasicRateSet & prStaRec->u2OperationalRateSet) !=
1702                  prBssInfo->u2BSSBasicRateSet) {
1703
1704                 u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
1705                 break;
1706             }
1707
1708             /* Accpet the Sta, update BSSBasicRateSet from Bss */
1709
1710             prStaRec->u2BSSBasicRateSet = prBssInfo->u2BSSBasicRateSet;
1711
1712             prStaRec->u2DesiredNonHTRateSet = (prStaRec->u2OperationalRateSet & RATE_SET_ALL_ABG);
1713
1714             if (BAND_2G4 == HIF_RX_HDR_GET_RF_BAND(prSwRfb->prHifRxHdr)) {
1715             #if 0 /* Marked by CMC 20111024 */
1716                 /* check if support 11n */
1717                 if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
1718
1719                     if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) {
1720                         prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
1721                     }
1722
1723
1724                     if (!(u2BSSBasicRateSet & RATE_SET_OFDM)) {
1725                         if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) {
1726                             prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
1727                         }
1728
1729                     }
1730
1731                 }
1732             #else
1733                 if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) {
1734                     prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
1735                 }
1736                 if (prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) {
1737                     prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
1738                 }
1739             #endif
1740             }
1741             else { /* (BAND_5G == prBssDesc->eBande) */
1742             #if 0 /* Marked by CMC 20111024 */
1743                 if (!(u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
1744
1745                     prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
1746                 }
1747                 ASSERT((prStaRec->u2OperationalRateSet & RATE_SET_HR_DSSS) == 0);
1748             #else
1749                 if (prStaRec->u2OperationalRateSet & RATE_SET_OFDM) {
1750                     prStaRec->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
1751                 }
1752             #endif
1753             }
1754
1755         }
1756         else {
1757             ASSERT(0);
1758             u2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
1759             break;
1760         }
1761
1762 #if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_HOTSPOT_PRIVACY_CHECK
1763         if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1764             if (prIeRsn) {
1765                 if (!kalP2PGetCipher(prAdapter->prGlueInfo)) {
1766                     u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED;
1767                     break;
1768                 }
1769             }
1770             else {
1771                 prStaRec->rSecInfo.fgAllowOnly1x = FALSE;
1772                 if (kalP2PGetCipher(prAdapter->prGlueInfo)) {
1773                     //Only Allow 1x
1774                     prStaRec->rSecInfo.fgAllowOnly1x = TRUE;
1775                     break;
1776                 }
1777             }
1778         }
1779 #endif
1780
1781     } while (FALSE);
1782
1783 #if CFG_ENABLE_WIFI_DIRECT
1784     if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) {
1785         #if 1 /* ICS */
1786         {
1787             PUINT_8 cp = (PUINT_8)&prAssocReqFrame->u2CapInfo;
1788                         P_UINT_8 prNewAssocReqIe = NULL;
1789                         
1790                         if (u2IELength) {
1791                                 prNewAssocReqIe= kalMemAlloc(u2IELength, VIR_MEM_TYPE);
1792                                 if (NULL == prNewAssocReqIe) {
1793                                         DBGLOG(AIS, WARN, ("allocate memory for (Re)assocReqIe fail,IELength=%d!\n",u2IELength));
1794                                         u2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
1795                                         return WLAN_STATUS_FAILURE;
1796                                         /*note: if return WLAN_STATUS_FAILURE, we wouldn't reply the GC!so he need wait util timeout
1797                                            should we change to WLAN_STATUS_SUCCESS? but memory allocate fail may also cause reply fail*/
1798                                 }
1799             } 
1800             if (prStaRec->fgIsReAssoc)
1801                 cp += 10;
1802             else
1803                 cp += 4;
1804             if (prStaRec->pucAssocReqIe) {
1805                                 kalMemFree(prStaRec->pucAssocReqIe, VIR_MEM_TYPE, prStaRec->u2AssocReqIeLen);
1806                                 prStaRec->pucAssocReqIe = NULL;
1807             }
1808             prStaRec->u2AssocReqIeLen = u2IELength;
1809             if (u2IELength) {
1810                                 prStaRec->pucAssocReqIe = prNewAssocReqIe;
1811                 kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength);
1812             }
1813         }
1814         #endif
1815             kalP2PUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8)&prAssocReqFrame->u2CapInfo, u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc);
1816         }
1817 #endif
1818
1819     *pu2StatusCode = u2StatusCode;
1820
1821     return WLAN_STATUS_SUCCESS;
1822
1823 } /* end of assocProcessRxAssocReqFrame() */
1824
1825
1826 /*----------------------------------------------------------------------------*/
1827 /*!
1828 * @brief This function is used to compose Common Information Elements for Association
1829 *        Response Frame.
1830 *
1831 * @param[in] prMsduInfo     Pointer to the composed MSDU_INFO_T.
1832 * @param[in] prBssInfo      Pointer to the BSS_INFO_T.
1833 *
1834 * @return (none)
1835 */
1836 /*----------------------------------------------------------------------------*/
1837 __KAL_INLINE__ VOID
1838 assocBuildReAssocRespFrameCommonIEs (
1839     IN P_ADAPTER_T prAdapter,
1840     IN P_MSDU_INFO_T prMsduInfo,
1841     IN P_BSS_INFO_T prBssInfo
1842     )
1843 {
1844     PUINT_8 pucBuffer;
1845     P_STA_RECORD_T prStaRec;
1846     UINT_8 ucSupRatesLen;
1847     UINT_8 ucExtSupRatesLen;
1848
1849
1850     ASSERT(prMsduInfo);
1851     ASSERT(prMsduInfo->eSrc == TX_PACKET_MGMT);
1852
1853     prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1854     ASSERT(prStaRec);
1855
1856
1857     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1858                           (UINT_32)prMsduInfo->u2FrameLength);
1859     ASSERT(pucBuffer);
1860
1861     if (prBssInfo->ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) {
1862
1863         ucSupRatesLen = ELEM_MAX_LEN_SUP_RATES;
1864         ucExtSupRatesLen = prBssInfo->ucAllSupportedRatesLen - ELEM_MAX_LEN_SUP_RATES;
1865     }
1866     else {
1867         ucSupRatesLen = prBssInfo->ucAllSupportedRatesLen;
1868         ucExtSupRatesLen = 0;
1869     }
1870
1871     /* Fill the Supported Rates element. */
1872     if (ucSupRatesLen) {
1873         SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_SUP_RATES;
1874         SUP_RATES_IE(pucBuffer)->ucLength = ucSupRatesLen;
1875         kalMemCopy(SUP_RATES_IE(pucBuffer)->aucSupportedRates,
1876                    prBssInfo->aucAllSupportedRates,
1877                    ucSupRatesLen);
1878
1879         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1880         pucBuffer += IE_SIZE(pucBuffer);
1881     }
1882
1883
1884     /* Fill the Extended Supported Rates element. */
1885     if (ucExtSupRatesLen) {
1886
1887         EXT_SUP_RATES_IE(pucBuffer)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
1888         EXT_SUP_RATES_IE(pucBuffer)->ucLength = ucExtSupRatesLen;
1889
1890         kalMemCopy(EXT_SUP_RATES_IE(pucBuffer)->aucExtSupportedRates,
1891                    &prBssInfo->aucAllSupportedRates[ucSupRatesLen],
1892                    ucExtSupRatesLen);
1893
1894         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1895     }
1896
1897     return;
1898 } /* end of assocBuildReAssocRespFrameCommonIEs() */
1899
1900
1901 /*----------------------------------------------------------------------------*/
1902 /*!
1903 * @brief This function will compose the (Re)Association Response frame
1904 *
1905 * @param[in] prStaRec               Pointer to the STA_RECORD_T
1906 * @param[in] pucBuffer              Pointer to the frame buffer.
1907 * @param[in] aucBssid               Given BSSID.
1908 * @param[in] u2CapInfo              Capability Field of current BSS.
1909 * @param[in out] pu2PayloadLen      Return the length of the composed fixed fields
1910 *
1911 * @return (none)
1912 */
1913 /*----------------------------------------------------------------------------*/
1914 __KAL_INLINE__ VOID
1915 assocComposeReAssocRespFrameHeaderAndFF (
1916     IN P_STA_RECORD_T prStaRec,
1917     IN PUINT_8 pucBuffer,
1918     IN UINT_8 aucBSSID[],
1919     IN UINT_16 u2CapInfo,
1920     IN OUT PUINT_16 pu2PayloadLen
1921     )
1922 {
1923     P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame;
1924     BOOLEAN fgIsReAssoc;
1925
1926     UINT_16 u2FrameCtrl;
1927
1928
1929     ASSERT(prStaRec);
1930     ASSERT(pucBuffer);
1931     ASSERT(aucBSSID);
1932     ASSERT(pu2PayloadLen);
1933
1934     prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T)pucBuffer;
1935     fgIsReAssoc = prStaRec->fgIsReAssoc;
1936
1937     //4 <1> Compose the frame header of the (Re)Association Request  frame.
1938     /* Fill the Frame Control field. */
1939     if (fgIsReAssoc) {
1940         u2FrameCtrl = MAC_FRAME_REASSOC_RSP;
1941     }
1942     else {
1943         u2FrameCtrl = MAC_FRAME_ASSOC_RSP;
1944     }
1945     //WLAN_SET_FIELD_16(&prAssocFrame->u2FrameCtrl, u2FrameCtrl);
1946     prAssocRspFrame->u2FrameCtrl = u2FrameCtrl; // NOTE(Kevin): Optimized for ARM
1947
1948     /* Fill the DA field with Target MAC Address. */
1949     COPY_MAC_ADDR(prAssocRspFrame->aucDestAddr, prStaRec->aucMacAddr);
1950
1951     /* Fill the SA field with current BSSID. */
1952     COPY_MAC_ADDR(prAssocRspFrame->aucSrcAddr, aucBSSID);
1953
1954     /* Fill the BSSID field with current BSSID. */
1955     COPY_MAC_ADDR(prAssocRspFrame->aucBSSID, aucBSSID);
1956
1957     /* Clear the SEQ/FRAG_NO field(HW won't overide the FRAG_NO, so we need to clear it). */
1958     prAssocRspFrame->u2SeqCtrl = 0;
1959
1960
1961     //4 <2> Compose the frame body's common fixed field part of the (Re)Association Request  frame.
1962     /* Fill the Capability Information field. */
1963     //WLAN_SET_FIELD_16(&prAssocFrame->u2CapInfo, u2CapInfo);
1964     prAssocRspFrame->u2CapInfo = u2CapInfo; // NOTE(Kevin): Optimized for ARM
1965
1966     //WLAN_SET_FIELD_16(&prAssocFrame->u2StatusCode, prStaRec->u2StatusCode);
1967     prAssocRspFrame->u2StatusCode = prStaRec->u2StatusCode; // NOTE(Kevin): Optimized for ARM
1968
1969     //WLAN_SET_FIELD_16(&prAssocFrame->u2AssocId, ((prStaRec->u2AssocId & AID_MASK) | AID_MSB));
1970     prAssocRspFrame->u2AssocId =
1971         ((prStaRec->u2AssocId & AID_MASK) | AID_MSB); // NOTE(Kevin): Optimized for ARM
1972
1973     *pu2PayloadLen = (CAP_INFO_FIELD_LEN +
1974                       STATUS_CODE_FIELD_LEN +
1975                       AID_FIELD_LEN);
1976
1977     return;
1978 } /* end of assocComposeReAssocRespFrameHeaderAndFF() */
1979
1980
1981 /*----------------------------------------------------------------------------*/
1982 /*!
1983 * @brief This function will send the (Re)Association Resp frame
1984 *
1985 * @param[in] prStaRec           Pointer to the STA_RECORD_T
1986 *
1987 * @retval WLAN_STATUS_RESOURCES No available resource for frame composing.
1988 * @retval WLAN_STATUS_SUCCESS   Successfully send frame to TX Module
1989 */
1990 /*----------------------------------------------------------------------------*/
1991 WLAN_STATUS
1992 assocSendReAssocRespFrame (
1993     IN P_ADAPTER_T      prAdapter,
1994     IN P_STA_RECORD_T   prStaRec
1995     )
1996 {
1997     P_BSS_INFO_T prBssInfo;
1998     P_MSDU_INFO_T prMsduInfo;
1999
2000     UINT_16 u2PayloadLen;
2001     UINT_16 u2EstimatedFrameLen;
2002     UINT_16 u2EstimatedExtraIELen;
2003     BOOLEAN fgIsReAssoc;
2004     UINT_32 i;
2005
2006
2007     ASSERT(prStaRec);
2008
2009
2010     //4 <1> Allocate a PKT_INFO_T for Authentication Frame
2011     fgIsReAssoc = prStaRec->fgIsReAssoc;
2012
2013     /* Init with MGMT Header Length + Length of Fixed Fields + Common IE Length */
2014     u2EstimatedFrameLen = MAC_TX_RESERVED_FIELD + \
2015                           WLAN_MAC_MGMT_HEADER_LEN + \
2016                           CAP_INFO_FIELD_LEN + \
2017                           STATUS_CODE_FIELD_LEN + \
2018                           AID_FIELD_LEN + \
2019                           (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + \
2020                           (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES));
2021
2022     /* + Extra IE Length */
2023     u2EstimatedExtraIELen = 0;
2024
2025     for (i = 0; i < sizeof(txAssocRespIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
2026         if (txAssocRespIETable[i].u2EstimatedFixedIELen != 0) {
2027             u2EstimatedExtraIELen += txAssocRespIETable[i].u2EstimatedFixedIELen;
2028         }
2029         else if (txAssocRespIETable[i].pfnCalculateVariableIELen != NULL) {
2030             u2EstimatedExtraIELen += (UINT_16)txAssocRespIETable[i].pfnCalculateVariableIELen(prAdapter,
2031                                                                                                         prStaRec->ucNetTypeIndex,
2032                                                                                                         prStaRec);
2033         }
2034
2035     }
2036
2037     u2EstimatedFrameLen += u2EstimatedExtraIELen;
2038
2039     /* Allocate a MSDU_INFO_T */
2040     if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == NULL) {
2041         DBGLOG(AAA, WARN, ("No PKT_INFO_T for sending (Re)Assoc Response.\n"));
2042         return WLAN_STATUS_RESOURCES;
2043     }
2044
2045     //4 <2> Compose (Re)Association Request frame header and fixed fields in MSDU_INfO_T.
2046     ASSERT(prStaRec->ucNetTypeIndex != NETWORK_TYPE_AIS_INDEX);
2047     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
2048
2049     /* Compose Header and Fixed Field */
2050     assocComposeReAssocRespFrameHeaderAndFF(prStaRec,
2051                                             (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
2052                                             prBssInfo->aucBSSID,
2053                                             prBssInfo->u2CapInfo,
2054                                             &u2PayloadLen);
2055
2056     //4 <3> Update information of MSDU_INFO_T
2057     ASSERT(prStaRec->ucNetTypeIndex < NETWORK_TYPE_INDEX_NUM);
2058
2059     prMsduInfo->eSrc = TX_PACKET_MGMT;
2060     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
2061     prMsduInfo->ucStaRecIndex = prStaRec->ucIndex;
2062     prMsduInfo->ucNetworkType = prStaRec->ucNetTypeIndex;
2063     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2064     prMsduInfo->fgIs802_1x = FALSE;
2065     prMsduInfo->fgIs802_11 = TRUE;
2066     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2067     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2068     prMsduInfo->pfTxDoneHandler = aaaFsmRunEventTxDone;
2069     prMsduInfo->fgIsBasicRate = TRUE;
2070
2071     //4 <4> Compose the frame body's IEs of the (Re)Association Request  frame.
2072     assocBuildReAssocRespFrameCommonIEs(prAdapter, prMsduInfo, prBssInfo);
2073
2074
2075     //4 <5> Compose IEs in MSDU_INFO_T
2076
2077     /* Append IE */
2078     for (i = 0; i < sizeof(txAssocRespIETable)/sizeof(APPEND_VAR_IE_ENTRY_T); i++) {
2079         if (txAssocRespIETable[i].pfnAppendIE) {
2080             txAssocRespIETable[i].pfnAppendIE(prAdapter, prMsduInfo);
2081         }
2082     }
2083
2084     /* TODO(Kevin): Also release the unused tail room of the composed MMPDU */
2085
2086     //4 <6> Enqueue the frame to send this (Re)Association request frame.
2087     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2088
2089     return WLAN_STATUS_SUCCESS;
2090
2091 } /* end of assocSendReAssocRespFrame() */
2092 #endif /* CFG_SUPPORT_AAA */
2093
2094