add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931 / mgmt / rsn.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rsn.c#2 $
3 */
4
5 /*! \file   "rsn.c"
6     \brief  This file including the 802.11i, wpa and wpa2(rsn) related function.
7
8     This file provided the macros and functions library support the wpa/rsn ie parsing,
9     cipher and AKM check to help the AP seleced deciding, tkip mic error handler and rsn PMKID support.
10 */
11
12
13
14 /*
15 ** $Log: rsn.c $
16  *
17  * 07 17 2012 yuche.tsai
18  * NULL
19  * Compile no error before trial run.
20  *
21  * 03 09 2012 chinglan.wang
22  * NULL
23  * Fix the condition error.
24  *
25  * 03 02 2012 terry.wu
26  * NULL
27  * Snc CFG80211 modification for ICS migration from branch 2.2.
28  *
29  * 03 02 2012 terry.wu
30  * NULL
31  * Sync CFG80211 modification from branch 2,2.
32  *
33  * 11 11 2011 wh.su
34  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
35  * modify the xlog related code.
36  *
37  * 11 10 2011 wh.su
38  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
39  * change the debug module level.
40  *
41  * 10 12 2011 wh.su
42  * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
43  * adding the 802.11w related function and define .
44  *
45  * 03 17 2011 chinglan.wang
46  * [WCXRP00000570] [MT6620 Wi-Fi][Driver] Add Wi-Fi Protected Setup v2.0 feature
47  * .
48  *
49  * 02 09 2011 wh.su
50  * [WCXRP00000432] [MT6620 Wi-Fi][Driver] Add STA privacy check at hotspot mode
51  * adding the code for check STA privacy bit at AP mode, .
52  *
53  * 12 24 2010 chinglan.wang
54  * NULL
55  * [MT6620][Wi-Fi] Modify the key management in the driver for WPS function.
56  *
57  * 12 13 2010 cp.wu
58  * [WCXRP00000260] [MT6620 Wi-Fi][Driver][Firmware] Create V1.1 branch for both firmware and driver
59  * create branch for Wi-Fi driver v1.1
60  *
61  * 11 05 2010 wh.su
62  * [WCXRP00000165] [MT6620 Wi-Fi] [Pre-authentication] Assoc req rsn ie use wrong pmkid value
63  * fixed the.pmkid value mismatch issue
64  *
65  * 11 03 2010 wh.su
66  * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
67  * Refine the HT rate disallow TKIP pairwise cipher .
68  *
69  * 10 04 2010 cp.wu
70  * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ENUM_NETWORK_TYPE_INDEX_T only
71  * remove ENUM_NETWORK_TYPE_T definitions
72  *
73  * 09 29 2010 yuche.tsai
74  * NULL
75  * Fix compile error, remove unused pointer in rsnGenerateRSNIE().
76  *
77  * 09 28 2010 wh.su
78  * NULL
79  * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
80  *
81  * 09 24 2010 wh.su
82  * NULL
83  * [WCXRP00005002][MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning.
84  *
85  * 09 06 2010 wh.su
86  * NULL
87  * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
88  *
89  * 08 30 2010 wh.su
90  * NULL
91  * remove non-used code.
92  *
93  * 08 19 2010 wh.su
94  * NULL
95  * adding the tx pkt call back handle for countermeasure.
96  *
97  * 07 24 2010 wh.su
98  *
99  * .support the Wi-Fi RSN
100  *
101  * 07 08 2010 cp.wu
102  *
103  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
104  *
105  * 06 21 2010 wh.su
106  * [WPD00003840][MT6620 5931] Security migration
107  * modify some code for concurrent network.
108  *
109  * 06 21 2010 cp.wu
110  * [WPD00003833][MT6620 and MT5931] Driver migration
111  * [WPD00003833][MT6620 and MT5931] Driver migration
112  * enable RX management frame handling.
113  *
114  * 06 19 2010 wh.su
115  * [WPD00003840][MT6620 5931] Security migration
116  * consdier the concurrent network setting.
117  *
118  * 06 18 2010 wh.su
119  * [WPD00003840][MT6620 5931] Security migration
120  * [WPD00003840] [MT6620 5931] Security migration
121  * migration from firmware.
122  *
123  * 05 27 2010 wh.su
124  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
125  * not indiate pmkid candidate while no new one scaned.
126  *
127  * 04 29 2010 wh.su
128  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
129  * adjsut the pre-authentication code.
130  *
131  * 03 03 2010 wh.su
132  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
133  * move the AIS specific variable for security to AIS specific structure.
134  *
135  * 03 03 2010 wh.su
136  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
137  * Fixed the pre-authentication timer not correctly init issue, and modify the security related callback function prototype.
138  *
139  * 01 27 2010 wh.su
140  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
141  * add and fixed some security function.
142  *
143  * 12 18 2009 cm.chang
144  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
145  * .
146  *
147  * Dec 8 2009 mtk01088
148  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
149  * change the name
150  *
151  * Dec 7 2009 mtk01088
152  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
153  * using the Rx0 port to indicate event
154  *
155  * Dec 4 2009 mtk01088
156  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
157  * refine the code for generate the WPA/RSN IE for assoc req
158  *
159  * Dec 3 2009 mtk01088
160  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
161  * adjust code for pmkid event
162  *
163  * Dec 1 2009 mtk01088
164  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
165  * adding the code for event (mic error and pmkid indicate) and do some function rename
166  *
167  * Nov 23 2009 mtk01088
168  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
169  * adding some security function
170  *
171  * Nov 19 2009 mtk01088
172  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
173  * adding some security feature, including pmkid
174  *
175  * Nov 18 2009 mtk01088
176  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
177  *
178 **
179 */
180
181 /*******************************************************************************
182 *                         C O M P I L E R   F L A G S
183 ********************************************************************************
184 */
185
186 /*******************************************************************************
187 *                    E X T E R N A L   R E F E R E N C E S
188 ********************************************************************************
189 */
190 #include "precomp.h"
191
192 #if CFG_RSN_MIGRATION
193
194 //extern PHY_ATTRIBUTE_T rPhyAttributes[];
195
196 /*******************************************************************************
197 *                              C O N S T A N T S
198 ********************************************************************************
199 */
200
201 /*******************************************************************************
202 *                             D A T A   T Y P E S
203 ********************************************************************************
204 */
205
206 /*******************************************************************************
207 *                            P U B L I C   D A T A
208 ********************************************************************************
209 */
210
211 /*******************************************************************************
212 *                           P R I V A T E   D A T A
213 ********************************************************************************
214 */
215
216 /*******************************************************************************
217 *                                 M A C R O S
218 ********************************************************************************
219 */
220
221 /*******************************************************************************
222 *                   F U N C T I O N   D E C L A R A T I O N S
223 ********************************************************************************
224 */
225
226 /*******************************************************************************
227 *                              F U N C T I O N S
228 ********************************************************************************
229 */
230
231 /*----------------------------------------------------------------------------*/
232 /*!
233 * \brief This routine is called to parse RSN IE.
234 *
235 * \param[in]  prInfoElem Pointer to the RSN IE
236 * \param[out] prRsnInfo Pointer to the BSSDescription structure to store the
237 **                  RSN information from the given RSN IE
238 *
239 * \retval TRUE - Succeeded
240 * \retval FALSE - Failed
241 */
242 /*----------------------------------------------------------------------------*/
243 BOOLEAN
244 rsnParseRsnIE (
245     IN  P_ADAPTER_T       prAdapter,
246     IN  P_RSN_INFO_ELEM_T prInfoElem,
247     OUT P_RSN_INFO_T      prRsnInfo
248     )
249 {
250     UINT_32               i;
251     INT_32                u4RemainRsnIeLen;
252     UINT_16               u2Version;
253     UINT_16               u2Cap = 0;
254     UINT_32               u4GroupSuite = RSN_CIPHER_SUITE_CCMP;
255     UINT_16               u2PairSuiteCount = 0;
256     UINT_16               u2AuthSuiteCount = 0;
257     PUINT_8               pucPairSuite = NULL;
258     PUINT_8               pucAuthSuite = NULL;
259     PUINT_8               cp;
260
261     DEBUGFUNC("rsnParseRsnIE");
262
263     ASSERT(prInfoElem);
264     ASSERT(prRsnInfo);
265
266     /* Verify the length of the RSN IE. */
267     if (prInfoElem->ucLength < 2) {
268         DBGLOG(RSN, TRACE, ("RSN IE length too short (length=%d)\n", prInfoElem->ucLength));
269         return FALSE;
270     }
271
272     /* Check RSN version: currently, we only support version 1. */
273     WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
274     if (u2Version != 1) {
275         DBGLOG(RSN, TRACE,("Unsupported RSN IE version: %d\n", u2Version));
276         return FALSE;
277     }
278
279     cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
280     u4RemainRsnIeLen = (INT_32) prInfoElem->ucLength - 2;
281
282     do {
283         if (u4RemainRsnIeLen == 0) {
284             break;
285         }
286
287         /* Parse the Group Key Cipher Suite field. */
288         if (u4RemainRsnIeLen < 4) {
289             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in group cipher suite (IE len: %d)\n",
290                 prInfoElem->ucLength));
291             return FALSE;
292         }
293
294         WLAN_GET_FIELD_32(cp, &u4GroupSuite);
295         cp += 4;
296         u4RemainRsnIeLen -= 4;
297
298         if (u4RemainRsnIeLen == 0) {
299             break;
300         }
301
302         /* Parse the Pairwise Key Cipher Suite Count field. */
303         if (u4RemainRsnIeLen < 2) {
304             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in pairwise cipher suite count (IE len: %d)\n",
305                 prInfoElem->ucLength));
306             return FALSE;
307         }
308
309         WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
310         cp += 2;
311         u4RemainRsnIeLen -= 2;
312
313         /* Parse the Pairwise Key Cipher Suite List field. */
314         i = (UINT_32) u2PairSuiteCount * 4;
315         if (u4RemainRsnIeLen < (INT_32) i) {
316             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in pairwise cipher suite list (IE len: %d)\n",
317                 prInfoElem->ucLength));
318             return FALSE;
319         }
320
321         pucPairSuite = cp;
322
323         cp += i;
324         u4RemainRsnIeLen -= (INT_32) i;
325
326         if (u4RemainRsnIeLen == 0) {
327             break;
328         }
329
330         /* Parse the Authentication and Key Management Cipher Suite Count field. */
331         if (u4RemainRsnIeLen < 2) {
332             DBGLOG(RSN, TRACE,("Fail to parse RSN IE in auth & key mgt suite count (IE len: %d)\n",
333                 prInfoElem->ucLength));
334             return FALSE;
335         }
336
337         WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
338         cp += 2;
339         u4RemainRsnIeLen -= 2;
340
341         /* Parse the Authentication and Key Management Cipher Suite List
342            field. */
343         i = (UINT_32) u2AuthSuiteCount * 4;
344         if (u4RemainRsnIeLen < (INT_32) i) {
345             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in auth & key mgt suite list (IE len: %d)\n",
346                 prInfoElem->ucLength));
347             return FALSE;
348         }
349
350         pucAuthSuite = cp;
351
352         cp += i;
353         u4RemainRsnIeLen -= (INT_32) i;
354
355         if (u4RemainRsnIeLen == 0) {
356             break;
357         }
358
359         /* Parse the RSN u2Capabilities field. */
360         if (u4RemainRsnIeLen < 2) {
361             DBGLOG(RSN, TRACE, ("Fail to parse RSN IE in RSN capabilities (IE len: %d)\n",
362                 prInfoElem->ucLength));
363             return FALSE;
364         }
365
366         WLAN_GET_FIELD_16(cp, &u2Cap);
367     } while (FALSE);
368
369     /* Save the RSN information for the BSS. */
370     prRsnInfo->ucElemId = ELEM_ID_RSN;
371
372     prRsnInfo->u2Version = u2Version;
373
374     prRsnInfo->u4GroupKeyCipherSuite = u4GroupSuite;
375
376     DBGLOG(RSN, LOUD, ("RSN: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
377         u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
378         (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
379         (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
380         (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
381
382     if (pucPairSuite) {
383         /* The information about the pairwise key cipher suites is present. */
384         if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
385             u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
386         }
387
388         prRsnInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
389
390         for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
391             WLAN_GET_FIELD_32(pucPairSuite,
392                 &prRsnInfo->au4PairwiseKeyCipherSuite[i]);
393             pucPairSuite += 4;
394
395             DBGLOG(RSN, LOUD, ("RSN: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
396                 (UINT_8)i, (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
397                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
398                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
399                 (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
400         }
401     }
402     else {
403         /* The information about the pairwise key cipher suites is not present.
404            Use the default chipher suite for RSN: CCMP. */
405         prRsnInfo->u4PairwiseKeyCipherSuiteCount = 1;
406         prRsnInfo->au4PairwiseKeyCipherSuite[0] = RSN_CIPHER_SUITE_CCMP;
407
408         DBGLOG(RSN, LOUD, ("RSN: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
409             (UCHAR) (prRsnInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
410             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
411             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
412             (UCHAR) ((prRsnInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
413     }
414
415     if (pucAuthSuite) {
416         /* The information about the authentication and key management suites
417            is present. */
418         if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
419             u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
420         }
421
422         prRsnInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
423
424         for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
425             WLAN_GET_FIELD_32(pucAuthSuite, &prRsnInfo->au4AuthKeyMgtSuite[i]);
426             pucAuthSuite += 4;
427
428             DBGLOG(RSN, LOUD, ("RSN: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
429                 (UINT_8)i, (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
430                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
431                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
432                 (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
433         }
434     }
435     else {
436         /* The information about the authentication and key management suites
437            is not present. Use the default AKM suite for RSN. */
438         prRsnInfo->u4AuthKeyMgtSuiteCount = 1;
439         prRsnInfo->au4AuthKeyMgtSuite[0] = RSN_AKM_SUITE_802_1X;
440
441         DBGLOG(RSN, LOUD, ("RSN: AKM suite: %02x-%02x-%02x-%02x (default)\n",
442             (UCHAR) (prRsnInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
443             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
444             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
445             (UCHAR) ((prRsnInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
446     }
447
448     prRsnInfo->u2RsnCap = u2Cap;
449 #if CFG_SUPPORT_802_11W
450     prRsnInfo->fgRsnCapPresent = TRUE;
451 #endif
452     DBGLOG(RSN, LOUD, ("RSN cap: 0x%04x\n", prRsnInfo->u2RsnCap));
453
454     return TRUE;
455 }   /* rsnParseRsnIE */
456
457
458 /*----------------------------------------------------------------------------*/
459 /*!
460 * \brief This routine is called to parse WPA IE.
461 *
462 * \param[in]  prInfoElem Pointer to the WPA IE.
463 * \param[out] prWpaInfo Pointer to the BSSDescription structure to store the
464 *                       WPA information from the given WPA IE.
465 *
466 * \retval TRUE Succeeded.
467 * \retval FALSE Failed.
468 */
469 /*----------------------------------------------------------------------------*/
470 BOOLEAN
471 rsnParseWpaIE (
472     IN  P_ADAPTER_T       prAdapter,
473     IN  P_WPA_INFO_ELEM_T prInfoElem,
474     OUT P_RSN_INFO_T      prWpaInfo
475     )
476 {
477     UINT_32               i;
478     INT_32                u4RemainWpaIeLen;
479     UINT_16               u2Version;
480     UINT_16               u2Cap = 0;
481     UINT_32               u4GroupSuite = WPA_CIPHER_SUITE_TKIP;
482     UINT_16               u2PairSuiteCount = 0;
483     UINT_16               u2AuthSuiteCount = 0;
484     PUCHAR                pucPairSuite = NULL;
485     PUCHAR                pucAuthSuite = NULL;
486     PUCHAR                cp;
487     BOOLEAN               fgCapPresent = FALSE;
488
489     DEBUGFUNC("rsnParseWpaIE");
490
491     ASSERT(prInfoElem);
492     ASSERT(prWpaInfo);
493
494     /* Verify the length of the WPA IE. */
495     if (prInfoElem->ucLength < 6) {
496         DBGLOG(RSN, TRACE,("WPA IE length too short (length=%d)\n", prInfoElem->ucLength));
497         return FALSE;
498     }
499
500     /* Check WPA version: currently, we only support version 1. */
501     WLAN_GET_FIELD_16(&prInfoElem->u2Version, &u2Version);
502     if (u2Version != 1) {
503         DBGLOG(RSN, TRACE, ("Unsupported WPA IE version: %d\n", u2Version));
504         return FALSE;
505     }
506
507     cp = (PUCHAR) &prInfoElem->u4GroupKeyCipherSuite;
508     u4RemainWpaIeLen = (INT_32) prInfoElem->ucLength - 6;
509
510     do {
511         if (u4RemainWpaIeLen == 0) {
512             break;
513         }
514
515         /* WPA_OUI      : 4
516            Version      : 2
517            GroupSuite   : 4
518            PairwiseCount: 2
519            PairwiseSuite: 4 * pairSuiteCount
520            AuthCount    : 2
521            AuthSuite    : 4 * authSuiteCount
522            Cap          : 2 */
523
524         /* Parse the Group Key Cipher Suite field. */
525         if (u4RemainWpaIeLen < 4) {
526             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in group cipher suite (IE len: %d)\n",
527                 prInfoElem->ucLength));
528             return FALSE;
529         }
530
531         WLAN_GET_FIELD_32(cp, &u4GroupSuite);
532         cp += 4;
533         u4RemainWpaIeLen -= 4;
534
535         if (u4RemainWpaIeLen == 0) {
536             break;
537         }
538
539         /* Parse the Pairwise Key Cipher Suite Count field. */
540         if (u4RemainWpaIeLen < 2) {
541             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in pairwise cipher suite count (IE len: %d)\n",
542                 prInfoElem->ucLength));
543             return FALSE;
544         }
545
546         WLAN_GET_FIELD_16(cp, &u2PairSuiteCount);
547         cp += 2;
548         u4RemainWpaIeLen -= 2;
549
550         /* Parse the Pairwise Key Cipher Suite List field. */
551         i = (UINT_32) u2PairSuiteCount * 4;
552         if (u4RemainWpaIeLen < (INT_32) i) {
553             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in pairwise cipher suite list (IE len: %d)\n",
554                 prInfoElem->ucLength));
555             return FALSE;
556         }
557
558         pucPairSuite = cp;
559
560         cp += i;
561         u4RemainWpaIeLen -= (INT_32) i;
562
563         if (u4RemainWpaIeLen == 0) {
564             break;
565         }
566
567         /* Parse the Authentication and Key Management Cipher Suite Count
568            field. */
569         if (u4RemainWpaIeLen < 2) {
570             DBGLOG(RSN, TRACE,("Fail to parse WPA IE in auth & key mgt suite count (IE len: %d)\n",
571                 prInfoElem->ucLength));
572             return FALSE;
573         }
574
575         WLAN_GET_FIELD_16(cp, &u2AuthSuiteCount);
576         cp += 2;
577         u4RemainWpaIeLen -= 2;
578
579         /* Parse the Authentication and Key Management Cipher Suite List
580            field. */
581         i = (UINT_32) u2AuthSuiteCount * 4;
582         if (u4RemainWpaIeLen < (INT_32) i) {
583             DBGLOG(RSN, TRACE, ("Fail to parse WPA IE in auth & key mgt suite list (IE len: %d)\n",
584                 prInfoElem->ucLength));
585             return FALSE;
586         }
587
588         pucAuthSuite = cp;
589
590         cp += i;
591         u4RemainWpaIeLen -= (INT_32) i;
592
593         if (u4RemainWpaIeLen == 0) {
594             break;
595         }
596
597         /* Parse the WPA u2Capabilities field. */
598         if (u4RemainWpaIeLen < 2) {
599             DBGLOG(RSN, TRACE, ("Fail to parse WPA IE in WPA capabilities (IE len: %d)\n",
600                 prInfoElem->ucLength));
601             return FALSE;
602         }
603
604         fgCapPresent = TRUE;
605         WLAN_GET_FIELD_16(cp, &u2Cap);
606         u4RemainWpaIeLen -= 2;
607     } while (FALSE);
608
609     /* Save the WPA information for the BSS. */
610
611     prWpaInfo->ucElemId = ELEM_ID_WPA;
612
613     prWpaInfo->u2Version = u2Version;
614
615     prWpaInfo->u4GroupKeyCipherSuite = u4GroupSuite;
616
617     DBGLOG(RSN, LOUD, ("WPA: version %d, group key cipher suite %02x-%02x-%02x-%02x\n",
618         u2Version, (UCHAR) (u4GroupSuite & 0x000000FF),
619         (UCHAR) ((u4GroupSuite >> 8) & 0x000000FF),
620         (UCHAR) ((u4GroupSuite >> 16) & 0x000000FF),
621         (UCHAR) ((u4GroupSuite >> 24) & 0x000000FF)));
622
623     if (pucPairSuite) {
624         /* The information about the pairwise key cipher suites is present. */
625         if (u2PairSuiteCount > MAX_NUM_SUPPORTED_CIPHER_SUITES) {
626             u2PairSuiteCount = MAX_NUM_SUPPORTED_CIPHER_SUITES;
627         }
628
629         prWpaInfo->u4PairwiseKeyCipherSuiteCount = (UINT_32) u2PairSuiteCount;
630
631         for (i = 0; i < (UINT_32) u2PairSuiteCount; i++) {
632             WLAN_GET_FIELD_32(pucPairSuite,
633                               &prWpaInfo->au4PairwiseKeyCipherSuite[i]);
634             pucPairSuite += 4;
635
636             DBGLOG(RSN, LOUD, ("WPA: pairwise key cipher suite [%d]: %02x-%02x-%02x-%02x\n",
637                 (UINT_8)i, (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[i] & 0x000000FF),
638                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 8) & 0x000000FF),
639                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 16) & 0x000000FF),
640                 (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[i] >> 24) & 0x000000FF)));
641         }
642     }
643     else {
644         /* The information about the pairwise key cipher suites is not present.
645            Use the default chipher suite for WPA: TKIP. */
646         prWpaInfo->u4PairwiseKeyCipherSuiteCount = 1;
647         prWpaInfo->au4PairwiseKeyCipherSuite[0] = WPA_CIPHER_SUITE_TKIP;
648
649         DBGLOG(RSN, LOUD, ("WPA: pairwise key cipher suite: %02x-%02x-%02x-%02x (default)\n",
650             (UCHAR) (prWpaInfo->au4PairwiseKeyCipherSuite[0] & 0x000000FF),
651             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 8) & 0x000000FF),
652             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 16) & 0x000000FF),
653             (UCHAR) ((prWpaInfo->au4PairwiseKeyCipherSuite[0] >> 24) & 0x000000FF)));
654     }
655
656     if (pucAuthSuite) {
657         /* The information about the authentication and key management suites
658            is present. */
659         if (u2AuthSuiteCount > MAX_NUM_SUPPORTED_AKM_SUITES) {
660             u2AuthSuiteCount = MAX_NUM_SUPPORTED_AKM_SUITES;
661         }
662
663         prWpaInfo->u4AuthKeyMgtSuiteCount = (UINT_32) u2AuthSuiteCount;
664
665         for (i = 0; i < (UINT_32) u2AuthSuiteCount; i++) {
666             WLAN_GET_FIELD_32(pucAuthSuite, &prWpaInfo->au4AuthKeyMgtSuite[i]);
667             pucAuthSuite += 4;
668
669             DBGLOG(RSN, LOUD, ("WPA: AKM suite [%d]: %02x-%02x-%02x-%02x\n",
670                 (UINT_8)i, (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[i] & 0x000000FF),
671                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 8) & 0x000000FF),
672                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 16) & 0x000000FF),
673                 (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[i] >> 24) & 0x000000FF)));
674         }
675     }
676     else {
677         /* The information about the authentication and key management suites
678            is not present. Use the default AKM suite for WPA. */
679         prWpaInfo->u4AuthKeyMgtSuiteCount = 1;
680         prWpaInfo->au4AuthKeyMgtSuite[0] = WPA_AKM_SUITE_802_1X;
681
682         DBGLOG(RSN, LOUD, ("WPA: AKM suite: %02x-%02x-%02x-%02x (default)\n",
683             (UCHAR) (prWpaInfo->au4AuthKeyMgtSuite[0] & 0x000000FF),
684             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 8) & 0x000000FF),
685             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 16) & 0x000000FF),
686             (UCHAR) ((prWpaInfo->au4AuthKeyMgtSuite[0] >> 24) & 0x000000FF)));
687     }
688
689     if (fgCapPresent) {
690         prWpaInfo->fgRsnCapPresent = TRUE;
691         prWpaInfo->u2RsnCap = u2Cap;
692         DBGLOG(RSN, LOUD, ("WPA: RSN cap: 0x%04x\n", prWpaInfo->u2RsnCap));
693     }
694     else {
695         prWpaInfo->fgRsnCapPresent = FALSE;
696         prWpaInfo->u2RsnCap = 0;
697     }
698
699     return TRUE;
700 }   /* rsnParseWpaIE */
701
702
703 /*----------------------------------------------------------------------------*/
704 /*!
705 * \brief This routine is called to search the desired pairwise
706 *        cipher suite from the MIB Pairwise Cipher Suite
707 *        configuration table.
708 *
709 * \param[in] u4Cipher The desired pairwise cipher suite to be searched
710 * \param[out] pu4Index Pointer to the index of the desired pairwise cipher in
711 *                      the table
712 *
713 * \retval TRUE - The desired pairwise cipher suite is found in the table.
714 * \retval FALSE - The desired pairwise cipher suite is not found in the
715 *                 table.
716 */
717 /*----------------------------------------------------------------------------*/
718 BOOLEAN
719 rsnSearchSupportedCipher (
720     IN  P_ADAPTER_T       prAdapter,
721     IN  UINT_32           u4Cipher,
722     OUT PUINT_32          pu4Index
723     )
724 {
725     UINT_8 i;
726     P_DOT11_RSNA_CONFIG_PAIRWISE_CIPHERS_ENTRY prEntry;
727
728     DEBUGFUNC("rsnSearchSupportedCipher");
729
730     ASSERT(pu4Index);
731
732     for (i = 0; i < MAX_NUM_SUPPORTED_CIPHER_SUITES; i++) {
733         prEntry = &prAdapter->rMib.dot11RSNAConfigPairwiseCiphersTable[i];
734         if (prEntry->dot11RSNAConfigPairwiseCipher == u4Cipher &&
735             prEntry->dot11RSNAConfigPairwiseCipherEnabled) {
736             *pu4Index = i;
737             return TRUE;
738         }
739     }
740     return FALSE;
741 }   /* rsnSearchSupportedCipher */
742
743
744 /*----------------------------------------------------------------------------*/
745 /*!
746 *
747 * \brief This routine is called to search the desired
748 *        authentication and key management (AKM) suite from the
749 *        MIB Authentication and Key Management Suites table.
750 *
751 * \param[in]  u4AkmSuite The desired AKM suite to be searched
752 * \param[out] pu4Index   Pointer to the index of the desired AKM suite in the
753 *                        table
754 *
755 * \retval TRUE  The desired AKM suite is found in the table.
756 * \retval FALSE The desired AKM suite is not found in the table.
757 *
758 * \note
759 */
760 /*----------------------------------------------------------------------------*/
761 BOOLEAN
762 rsnSearchAKMSuite (
763     IN  P_ADAPTER_T       prAdapter,
764     IN  UINT_32           u4AkmSuite,
765     OUT PUINT_32          pu4Index
766     )
767 {
768     UINT_8 i;
769     P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
770
771     DEBUGFUNC("rsnSearchAKMSuite");
772
773     ASSERT(pu4Index);
774
775     for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
776         prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
777         if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite &&
778             prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) {
779             *pu4Index = i;
780             return TRUE;
781         }
782     }
783     return FALSE;
784 }   /* rsnSearchAKMSuite */
785
786
787 /*----------------------------------------------------------------------------*/
788 /*!
789 * \brief This routine is called to perform RSNA or TSN policy
790 *        selection for a given BSS.
791 *
792 * \param[in]  prBss Pointer to the BSS description
793 *
794 * \retval TRUE - The RSNA/TSN policy selection for the given BSS is
795 *                successful. The selected pairwise and group cipher suites
796 *                are returned in the BSS description.
797 * \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed.
798 *                 The driver shall not attempt to join the given BSS.
799 *
800 * \note The Encrypt status matched score will save to bss for final ap select.
801 */
802 /*----------------------------------------------------------------------------*/
803 BOOLEAN
804 rsnPerformPolicySelection (
805     IN  P_ADAPTER_T         prAdapter,
806     IN  P_BSS_DESC_T        prBss
807     )
808 {
809 #if CFG_SUPPORT_802_11W
810     INT_32                  i;
811     UINT_32                 j;
812 #else
813     UINT_32                 i, j;
814 #endif
815     BOOLEAN                 fgSuiteSupported;
816     UINT_32                 u4PairwiseCipher = 0;
817     UINT_32                 u4GroupCipher = 0;
818     UINT_32                 u4AkmSuite = 0;
819     P_RSN_INFO_T            prBssRsnInfo;
820     ENUM_NETWORK_TYPE_INDEX_T eNetwotkType;
821     BOOLEAN                 fgIsWpsActive = (BOOLEAN)FALSE;
822
823     DEBUGFUNC("rsnPerformPolicySelection");
824
825     ASSERT(prBss);
826
827     DBGLOG(RSN, TRACE, ("rsnPerformPolicySelection\n"));
828     //Todo::
829     eNetwotkType = NETWORK_TYPE_AIS_INDEX;
830
831     prBss->u4RsnSelectedPairwiseCipher = 0;
832     prBss->u4RsnSelectedGroupCipher = 0;
833     prBss->u4RsnSelectedAKMSuite = 0;
834     prBss->ucEncLevel = 0;
835
836 #if CFG_SUPPORT_WPS
837     fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo);
838
839     /* CR1640, disable the AP select privacy check */
840     if ( fgIsWpsActive &&
841         (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) &&
842         (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) {
843         DBGLOG(RSN, TRACE,("-- Skip the Protected BSS check\n"));
844         return TRUE;
845     }
846 #endif
847
848     /* Protection is not required in this BSS. */
849     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0 ) {
850
851         if (secEnabledInAis(prAdapter) == FALSE) {
852             DBGLOG(RSN, TRACE,("-- No Protected BSS\n"));
853             return TRUE;
854         }
855         else {
856             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
857             return FALSE;
858         }
859     }
860
861     /* Protection is required in this BSS. */
862     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) {
863         if (secEnabledInAis(prAdapter) == FALSE) {
864             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
865             return FALSE;
866         }
867     }
868
869     if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA ||
870         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK ||
871         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
872
873         if (prBss->fgIEWPA) {
874             prBssRsnInfo = &prBss->rWPAInfo;
875         }
876         else {
877             DBGLOG(RSN, TRACE, ("WPA Information Element does not exist.\n"));
878             return FALSE;
879         }
880     }
881     else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 ||
882         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) {
883
884         if (prBss->fgIERSN) {
885             prBssRsnInfo = &prBss->rRSNInfo;
886         }
887         else {
888             DBGLOG(RSN, TRACE, ("RSN Information Element does not exist.\n"));
889             return FALSE;
890         }
891     }
892     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) {
893         /* If the driver is configured to use WEP only, ignore this BSS. */
894         DBGLOG(RSN, TRACE, ("-- Not WEP-only legacy BSS\n"));
895         return FALSE;
896     }
897     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) {
898         /* If the driver is configured to use WEP only, use this BSS. */
899         DBGLOG(RSN, TRACE, ("-- WEP-only legacy BSS\n"));
900         return TRUE;
901     }
902
903     if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 &&
904         GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) ==
905         CIPHER_SUITE_NONE) {
906         /* Since the pairwise cipher use the same cipher suite as the group
907            cipher in the BSS, we check the group cipher suite against the
908            current encryption status. */
909         fgSuiteSupported = FALSE;
910
911         switch (prBssRsnInfo->u4GroupKeyCipherSuite) {
912         case WPA_CIPHER_SUITE_CCMP:
913         case RSN_CIPHER_SUITE_CCMP:
914              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
915                  ENUM_ENCRYPTION3_ENABLED) {
916                  fgSuiteSupported = TRUE;
917              }
918              break;
919
920         case WPA_CIPHER_SUITE_TKIP:
921         case RSN_CIPHER_SUITE_TKIP:
922              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
923                  ENUM_ENCRYPTION2_ENABLED) {
924                  fgSuiteSupported = TRUE;
925              }
926              break;
927
928         case WPA_CIPHER_SUITE_WEP40:
929         case WPA_CIPHER_SUITE_WEP104:
930              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
931                  ENUM_ENCRYPTION1_ENABLED) {
932                  fgSuiteSupported = TRUE;
933              }
934              break;
935         }
936
937         if (fgSuiteSupported) {
938             u4PairwiseCipher = WPA_CIPHER_SUITE_NONE;
939             u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
940         }
941 #if DBG
942         else {
943             DBGLOG(RSN, TRACE, ("Inproper encryption status %d for group-key-only BSS\n",
944                 prAdapter->rWifiVar.rConnSettings.eEncStatus));
945         }
946 #endif
947     }
948     else {
949         fgSuiteSupported = FALSE;
950
951         DBGLOG(RSN, TRACE, ("eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus,
952             prBssRsnInfo->u4PairwiseKeyCipherSuiteCount,
953             prBssRsnInfo->au4PairwiseKeyCipherSuite[0]));
954         /* Select pairwise/group ciphers */
955         switch (prAdapter->rWifiVar.rConnSettings.eEncStatus)
956         {
957         case ENUM_ENCRYPTION3_ENABLED:
958              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
959                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
960                      == CIPHER_SUITE_CCMP) {
961                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
962                  }
963              }
964              u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
965              break;
966
967         case ENUM_ENCRYPTION2_ENABLED:
968              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
969                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
970                      == CIPHER_SUITE_TKIP) {
971                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
972                  }
973              }
974              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
975                  CIPHER_SUITE_CCMP) {
976                  DBGLOG(RSN, TRACE, ("Cannot join CCMP BSS\n"));
977              }
978              else {
979                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
980              }
981              break;
982
983         case ENUM_ENCRYPTION1_ENABLED:
984              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
985                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
986                      == CIPHER_SUITE_WEP40 ||
987                      GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
988                      == CIPHER_SUITE_WEP104) {
989                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
990                  }
991              }
992              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
993                  CIPHER_SUITE_CCMP ||
994                  GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
995                  CIPHER_SUITE_TKIP) {
996                  DBGLOG(RSN, TRACE, ("Cannot join CCMP/TKIP BSS\n"));
997              }
998              else {
999                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1000              }
1001              break;
1002
1003         default:
1004              break;
1005         }
1006     }
1007
1008     /* Exception handler */
1009     /* If we cannot find proper pairwise and group cipher suites to join the
1010        BSS, do not check the supported AKM suites. */
1011     if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
1012         DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher (0x%08lx/0x%08lx)\n",
1013             u4PairwiseCipher, u4GroupCipher));
1014         return FALSE;
1015     }
1016
1017 #if CFG_ENABLE_WIFI_DIRECT
1018     if ((prAdapter->fgIsP2PRegistered) &&
1019         (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) {
1020         if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1021             u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1022             u4AkmSuite != RSN_AKM_SUITE_PSK) {
1023             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for P2P network (0x%08lx/0x%08lx)\n",
1024                 u4PairwiseCipher, u4GroupCipher));
1025             return FALSE;
1026         }
1027     }
1028 #endif
1029
1030 #if CFG_ENABLE_BT_OVER_WIFI
1031         if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) {
1032             if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1033                 u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1034                 u4AkmSuite != RSN_AKM_SUITE_PSK) {
1035             }
1036             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08lx/0x%08lx)\n",
1037                 u4PairwiseCipher, u4GroupCipher));
1038             return FALSE;
1039         }
1040 #endif
1041
1042
1043     /* Verify if selected pairwisse cipher is supported */
1044     fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i);
1045
1046     /* Verify if selected group cipher is supported */
1047     if (fgSuiteSupported) {
1048         fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i);
1049     }
1050
1051     if (!fgSuiteSupported) {
1052         DBGLOG(RSN, TRACE, ("Failed to support selected pairwise/group cipher (0x%08lx/0x%08lx)\n",
1053             u4PairwiseCipher, u4GroupCipher));
1054         return FALSE;
1055     }
1056
1057     /* Select AKM */
1058     /* If the driver cannot support any authentication suites advertised in
1059        the given BSS, we fail to perform RSNA policy selection. */
1060     /* Attempt to find any overlapping supported AKM suite. */
1061 #if CFG_SUPPORT_802_11W
1062     if (i != 0)
1063         for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--)
1064 #else
1065     for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++)
1066 #endif
1067     {
1068         if (rsnSearchAKMSuite(prAdapter,
1069             prBssRsnInfo->au4AuthKeyMgtSuite[i],
1070             &j)) {
1071             u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i];
1072             break;
1073         }
1074     }
1075
1076     if (u4AkmSuite == 0) {
1077         DBGLOG(RSN, TRACE, ("Cannot support any AKM suites\n"));
1078         return FALSE;
1079     }
1080
1081     DBGLOG(RSN, TRACE, ("Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
1082         (UINT_8) (u4PairwiseCipher & 0x000000FF),
1083         (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
1084         (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
1085         (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
1086         (UINT_8) (u4GroupCipher & 0x000000FF),
1087         (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
1088         (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
1089         (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)));
1090
1091     DBGLOG(RSN, TRACE, ("Selected AKM suite: %02x-%02x-%02x-%02x\n",
1092         (UINT_8) (u4AkmSuite & 0x000000FF),
1093         (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
1094         (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF),
1095         (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)));
1096
1097 #if CFG_SUPPORT_802_11W
1098     DBGLOG(RSN, TRACE, ("MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)));
1099
1100     if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1101         if (!prBssRsnInfo->fgRsnCapPresent) {
1102             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability.\n"));
1103             return FALSE;
1104         }
1105         else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
1106             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required\n"));
1107             return FALSE;
1108         }
1109         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1110     }
1111     else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1112         if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) ||
1113             (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) {
1114             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1115         }
1116         else {
1117             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1118         }
1119     }
1120     else {
1121         if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) {
1122             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability\n"));
1123             return FALSE;
1124         }
1125         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1126     }
1127     DBGLOG(RSN, TRACE, ("fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection));
1128 #endif
1129
1130     if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP){
1131         prBss->ucEncLevel = 3;
1132     }
1133     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP){
1134         prBss->ucEncLevel = 2;
1135     }
1136     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 ||
1137         GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) {
1138         prBss->ucEncLevel = 1;
1139     }
1140     else {
1141         ASSERT(FALSE);
1142     }
1143     prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher;
1144     prBss->u4RsnSelectedGroupCipher = u4GroupCipher;
1145     prBss->u4RsnSelectedAKMSuite = u4AkmSuite;
1146
1147     return TRUE;
1148
1149 }  /* rsnPerformPolicySelection */
1150
1151
1152 /*----------------------------------------------------------------------------*/
1153 /*!
1154 * \brief This routine is called to generate WPA IE for beacon frame.
1155 *
1156 * \param[in] pucIeStartAddr Pointer to put the generated WPA IE.
1157 *
1158 * \return The append WPA-None IE length
1159 * \note
1160 *      Called by: JOIN module, compose beacon IE
1161 */
1162 /*----------------------------------------------------------------------------*/
1163 VOID
1164 rsnGenerateWpaNoneIE (
1165     IN  P_ADAPTER_T       prAdapter,
1166     IN  P_MSDU_INFO_T     prMsduInfo
1167     )
1168 {
1169     UINT_32               i;
1170     P_WPA_INFO_ELEM_T     prWpaIE;
1171     UINT_32               u4Suite;
1172     UINT_16               u2SuiteCount;
1173     PUINT_8               cp, cp2;
1174     UINT_8                ucExpendedLen = 0;
1175     PUINT_8               pucBuffer;
1176     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1177
1178     DEBUGFUNC("rsnGenerateWpaNoneIE");
1179
1180     ASSERT(prMsduInfo);
1181
1182     if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) {
1183         return;
1184     }
1185
1186     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1187
1188     if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1189         return;
1190
1191     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1192                           (UINT_32)prMsduInfo->u2FrameLength);
1193
1194     ASSERT(pucBuffer);
1195
1196     prWpaIE = (P_WPA_INFO_ELEM_T)(pucBuffer);
1197
1198     /* Start to construct a WPA IE. */
1199     /* Fill the Element ID field. */
1200     prWpaIE->ucElemId = ELEM_ID_WPA;
1201
1202     /* Fill the OUI and OUI Type fields. */
1203     prWpaIE->aucOui[0] = 0x00;
1204     prWpaIE->aucOui[1] = 0x50;
1205     prWpaIE->aucOui[2] = 0xF2;
1206     prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA;
1207
1208     /* Fill the Version field. */
1209     WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1);    /* version 1 */
1210     ucExpendedLen = 6;
1211
1212     /* Fill the Pairwise Key Cipher Suite List field. */
1213     u2SuiteCount = 0;
1214     cp = (PUINT_8)&prWpaIE->aucPairwiseKeyCipherSuite1[0];
1215
1216     if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) {
1217         u4Suite = WPA_CIPHER_SUITE_CCMP;
1218     }
1219     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) {
1220         u4Suite = WPA_CIPHER_SUITE_TKIP;
1221     }
1222     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) {
1223         u4Suite = WPA_CIPHER_SUITE_WEP104;
1224     }
1225     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) {
1226         u4Suite = WPA_CIPHER_SUITE_WEP40;
1227     }
1228     else {
1229         u4Suite = WPA_CIPHER_SUITE_TKIP;
1230     }
1231
1232     WLAN_SET_FIELD_32(cp, u4Suite);
1233     u2SuiteCount++;
1234     ucExpendedLen += 4;
1235     cp += 4;
1236
1237     /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */
1238     WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite);
1239     ucExpendedLen += 4;
1240
1241     /* Fill the Pairwise Key Cipher Suite Count field. */
1242     WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount);
1243     ucExpendedLen += 2;
1244
1245     cp2 = cp;
1246
1247     /* Fill the Authentication and Key Management Suite List field. */
1248     u2SuiteCount = 0;
1249     cp += 2;
1250
1251     if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) {
1252         u4Suite = WPA_AKM_SUITE_802_1X;
1253     }
1254     else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) {
1255         u4Suite = WPA_AKM_SUITE_PSK;
1256     }
1257     else {
1258         u4Suite = WPA_AKM_SUITE_NONE;
1259     }
1260
1261     /* This shall be the only avaiable value for current implementation */
1262     ASSERT(u4Suite == WPA_AKM_SUITE_NONE);
1263
1264     WLAN_SET_FIELD_32(cp, u4Suite);
1265     u2SuiteCount++;
1266     ucExpendedLen += 4;
1267     cp += 4;
1268
1269     /* Fill the Authentication and Key Management Suite Count field. */
1270     WLAN_SET_FIELD_16(cp2, u2SuiteCount);
1271     ucExpendedLen += 2;
1272
1273     /* Fill the Length field. */
1274     prWpaIE->ucLength = (UINT_8)ucExpendedLen;
1275
1276     /* Increment the total IE length for the Element ID and Length fields. */
1277     prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1278
1279 } /* rsnGenerateWpaNoneIE */
1280
1281
1282 /*----------------------------------------------------------------------------*/
1283 /*!
1284 *
1285 * \brief This routine is called to generate WPA IE for
1286 *        associate request frame.
1287 *
1288 * \param[in]  prCurrentBss     The Selected BSS description
1289 *
1290 * \retval The append WPA IE length
1291 *
1292 * \note
1293 *      Called by: AIS module, Associate request
1294 */
1295 /*----------------------------------------------------------------------------*/
1296 VOID
1297 rsnGenerateWPAIE (
1298     IN  P_ADAPTER_T       prAdapter,
1299     IN  P_MSDU_INFO_T     prMsduInfo
1300     )
1301 {
1302     PUCHAR                cp;
1303     PUINT_8               pucBuffer;
1304     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1305
1306     DEBUGFUNC("rsnGenerateWPAIE");
1307
1308     ASSERT(prMsduInfo);
1309
1310     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1311                           (UINT_32)prMsduInfo->u2FrameLength);
1312
1313     ASSERT(pucBuffer);
1314
1315     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1316
1317     //if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1318     //    return;
1319
1320 #if CFG_ENABLE_WIFI_DIRECT 
1321     if ((1 /* prCurrentBss->fgIEWPA */ && 
1322                 ((prAdapter->fgIsP2PRegistered) && 
1323                 (eNetworkId == NETWORK_TYPE_P2P_INDEX) && 
1324                 (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || 
1325                 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1326         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) 
1327 #else 
1328         if ((1 /* prCurrentBss->fgIEWPA */ && 
1329         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1330         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) 
1331 #endif
1332     {
1333         /* Construct a WPA IE for association request frame. */
1334         WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA;
1335         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1336         WPA_IE(pucBuffer)->aucOui[0] = 0x00;
1337         WPA_IE(pucBuffer)->aucOui[1] = 0x50;
1338         WPA_IE(pucBuffer)->aucOui[2] = 0xF2;
1339         WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA;
1340         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1);
1341
1342 #if CFG_ENABLE_WIFI_DIRECT
1343         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1344         {
1345             WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP);
1346         }
1347         else
1348 #endif
1349         WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
1350             prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher);
1351
1352         cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1353
1354         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1355 #if CFG_ENABLE_WIFI_DIRECT
1356         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1357         {
1358             WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP);
1359         }
1360         else
1361 #endif
1362         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher);
1363         cp += 4;
1364
1365         WLAN_SET_FIELD_16(cp, 1);
1366         cp += 2;
1367 #if CFG_ENABLE_WIFI_DIRECT
1368         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1369         {
1370             WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK);
1371         }
1372         else
1373 #endif
1374         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite);
1375         cp += 4;
1376
1377         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1378
1379         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1380     }
1381
1382 } /* rsnGenerateWPAIE */
1383
1384
1385 /*----------------------------------------------------------------------------*/
1386 /*!
1387 *
1388 * \brief This routine is called to generate RSN IE for
1389 *        associate request frame.
1390 *
1391 * \param[in]  prMsduInfo     The Selected BSS description
1392 *
1393 * \retval The append RSN IE length
1394 *
1395 * \note
1396 *      Called by: AIS module, P2P module, BOW module Associate request
1397 */
1398 /*----------------------------------------------------------------------------*/
1399 VOID
1400 rsnGenerateRSNIE (
1401     IN  P_ADAPTER_T       prAdapter,
1402     IN  P_MSDU_INFO_T     prMsduInfo
1403     )
1404 {
1405     UINT_32               u4Entry;
1406     PUCHAR                cp;
1407     //UINT_8                ucExpendedLen = 0;
1408     PUINT_8               pucBuffer;
1409     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1410     P_STA_RECORD_T  prStaRec;
1411
1412     DEBUGFUNC("rsnGenerateRSNIE");
1413
1414     ASSERT(prMsduInfo);
1415
1416     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1417                           (UINT_32)prMsduInfo->u2FrameLength);
1418
1419     ASSERT(pucBuffer);
1420
1421     /* Todo:: network id */
1422     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1423
1424     if (
1425 #if CFG_ENABLE_WIFI_DIRECT
1426         ((prAdapter->fgIsP2PRegistered) &&
1427         (eNetworkId == NETWORK_TYPE_P2P_INDEX) &&
1428         (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) ||
1429 #endif
1430 #if CFG_ENABLE_BT_OVER_WIFI
1431         (eNetworkId == NETWORK_TYPE_BOW_INDEX) ||
1432 #endif
1433         (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ &&
1434         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ||
1435         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK))))
1436     {
1437         /* Construct a RSN IE for association request frame. */
1438         RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN;
1439         RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED;
1440         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); // Version
1441         WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite,
1442             prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); // Group key suite
1443         cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1444         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1445         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher);
1446         cp += 4;
1447         WLAN_SET_FIELD_16(cp, 1); // AKM suite count
1448         cp += 2;
1449         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); // AKM suite
1450         cp += 4;
1451         WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo); // Capabilities
1452 #if CFG_SUPPORT_802_11W
1453         if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) {
1454             if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1455                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); // Capabilities
1456             }
1457             else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1458                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); // Capabilities
1459             }
1460         }
1461 #endif
1462         cp += 2;
1463
1464         if (eNetworkId == NETWORK_TYPE_AIS_INDEX)
1465             prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1466
1467         if (eNetworkId == NETWORK_TYPE_AIS_INDEX &&
1468             rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) {
1469             //DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n"));
1470             //DBGLOG(RSN, TRACE, ("addr " MACSTR" PMKID "MACSTR"\n",
1471             //    MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID), MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1472             if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) {
1473                 RSN_IE(pucBuffer)->ucLength = 38;
1474                 WLAN_SET_FIELD_16(cp, 1); // PMKID count
1475                 cp += 2;
1476                 DBGLOG(RSN, TRACE, ("BSSID "MACSTR" ind=%d\n", MAC2STR(prStaRec->aucMacAddr), u4Entry));
1477                 DBGLOG(RSN, TRACE, ("use PMKID "MACSTR"\n", MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1478                 kalMemCopy(cp, (PVOID)prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID,
1479                     sizeof(PARAM_PMKID_VALUE));
1480                 //ucExpendedLen = 40;
1481             }
1482             else {
1483                 WLAN_SET_FIELD_16(cp, 0); // PMKID count
1484                 //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1485 #if CFG_SUPPORT_802_11W
1486                 cp += 2;
1487                 RSN_IE(pucBuffer)->ucLength += 2;
1488 #endif
1489             }
1490         }
1491         else {
1492             WLAN_SET_FIELD_16(cp, 0); // PMKID count
1493             //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1494 #if CFG_SUPPORT_802_11W
1495             cp += 2;
1496             RSN_IE(pucBuffer)->ucLength += 2;
1497 #endif
1498         }
1499
1500 #if CFG_SUPPORT_802_11W
1501         if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) && (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */ ) {
1502             WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC);
1503             cp += 4;
1504             RSN_IE(pucBuffer)->ucLength += 4;
1505         }
1506 #endif
1507         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1508     }
1509
1510 } /* rsnGenerateRSNIE */
1511
1512 /*----------------------------------------------------------------------------*/
1513 /*!
1514 * \brief Parse the given IE buffer and check if it is WFA IE and return Type and
1515 *        SubType for further process.
1516 *
1517 * \param[in] pucBuf             Pointer to the buffer of WFA Information Element.
1518 * \param[out] pucOuiType        Pointer to the storage of OUI Type.
1519 * \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version.
1520
1521 * \retval TRUE  Parse IE ok
1522 * \retval FALSE Parse IE fail
1523 */
1524 /*----------------------------------------------------------------------------*/
1525 BOOLEAN
1526 rsnParseCheckForWFAInfoElem (
1527     IN  P_ADAPTER_T       prAdapter,
1528     IN  PUINT_8           pucBuf,
1529     OUT PUINT_8           pucOuiType,
1530     OUT PUINT_16          pu2SubTypeVersion
1531     )
1532 {
1533     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
1534     P_IE_WFA_T prWfaIE;
1535
1536     ASSERT(pucBuf);
1537     ASSERT(pucOuiType);
1538     ASSERT(pu2SubTypeVersion);
1539     prWfaIE = (P_IE_WFA_T)pucBuf;
1540
1541     do {
1542         if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
1543             break;
1544         }
1545         else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
1546                  prWfaIE->aucOui[1] != aucWfaOui[1] ||
1547                  prWfaIE->aucOui[2] != aucWfaOui[2]) {
1548             break;
1549         }
1550
1551         *pucOuiType = prWfaIE->ucOuiType;
1552         WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion);
1553
1554         return TRUE;
1555     }
1556     while (FALSE);
1557
1558     return FALSE;
1559
1560 } /* end of rsnParseCheckForWFAInfoElem() */
1561
1562 #if CFG_SUPPORT_AAA
1563 /*----------------------------------------------------------------------------*/
1564 /*!
1565 * \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK
1566 *
1567 * \param[in] prAdapter             Pointer to Adapter
1568 * \param[in] prSwRfb               Pointer to the rx buffer
1569 * \param[in] pIE                      Pointer rthe buffer of Information Element.
1570 * \param[out] prStatusCode     Pointer to the return status code.
1571
1572 * \retval none
1573 */
1574 /*----------------------------------------------------------------------------*/
1575 void
1576 rsnParserCheckForRSNCCMPPSK(
1577     P_ADAPTER_T           prAdapter,
1578     P_RSN_INFO_ELEM_T     prIe,
1579     PUINT_16              pu2StatusCode
1580     )
1581 {
1582
1583     RSN_INFO_T            rRsnIe;
1584
1585     ASSERT(prAdapter);
1586     ASSERT(prIe);
1587     ASSERT(pu2StatusCode);
1588
1589     *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
1590
1591     if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) {
1592         if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) {
1593             *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER;
1594             return;
1595         }
1596         if ((rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP)) {
1597             *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER;
1598             return;
1599         }
1600         if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) {
1601             *pu2StatusCode = STATUS_CODE_INVALID_AKMP;
1602             return;
1603         }
1604
1605         DBGLOG(RSN, TRACE, ("RSN with CCMP-PSK\n" ));
1606             *pu2StatusCode = WLAN_STATUS_SUCCESS;
1607     }
1608
1609 }
1610 #endif
1611
1612 /*----------------------------------------------------------------------------*/
1613 /*!
1614 * \brief This routine is called to generate an authentication event to NDIS.
1615 *
1616 * \param[in] u4Flags Authentication event: \n
1617 *                     PARAM_AUTH_REQUEST_REAUTH 0x01 \n
1618 *                     PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n
1619 *                     PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n
1620 *                     PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n
1621 *
1622 * \return (none)
1623 */
1624 /*----------------------------------------------------------------------------*/
1625 VOID
1626 rsnGenMicErrorEvent (
1627     IN  P_ADAPTER_T       prAdapter,
1628     IN  BOOLEAN           fgFlags
1629     )
1630 {
1631     P_PARAM_AUTH_EVENT_T prAuthEvent;
1632
1633     DEBUGFUNC("rsnGenMicErrorEvent");
1634
1635     prAuthEvent = (P_PARAM_AUTH_EVENT_T)prAdapter->aucIndicationEventBuffer;
1636
1637     /* Status type: Authentication Event */
1638     prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
1639
1640     /* Authentication request */
1641     prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
1642     kalMemCopy((PVOID)prAuthEvent->arRequest[0].arBssid, (PVOID)prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN);
1643
1644     if (fgFlags == TRUE)
1645         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
1646     else
1647         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
1648
1649     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1650         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1651         (PVOID)prAuthEvent,
1652         sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
1653
1654 } /* rsnGenMicErrorEvent */
1655
1656
1657 /*----------------------------------------------------------------------------*/
1658 /*!
1659 * \brief This routine is called to handle TKIP MIC failures.
1660 *
1661 * \param[in] adapter_p Pointer to the adapter object data area.
1662 * \param[in] prSta Pointer to the STA which occur MIC Error
1663 * \param[in] fgErrorKeyType type of error key
1664 *
1665 * \retval none
1666 */
1667 /*----------------------------------------------------------------------------*/
1668 VOID
1669 rsnTkipHandleMICFailure (
1670     IN  P_ADAPTER_T       prAdapter,
1671     IN  P_STA_RECORD_T    prSta,
1672     IN  BOOLEAN           fgErrorKeyType
1673     )
1674 {
1675     //UINT_32               u4RsnaCurrentMICFailTime;
1676     //P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1677
1678     DEBUGFUNC("rsnTkipHandleMICFailure");
1679
1680     ASSERT(prAdapter);
1681 #if 1
1682     rsnGenMicErrorEvent(prAdapter,/* prSta,*/ fgErrorKeyType);
1683
1684     /* Generate authentication request event. */
1685     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1686         fgErrorKeyType));
1687 #else
1688     ASSERT(prSta);
1689
1690     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1691
1692     /* Record the MIC error occur time. */
1693     GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime);
1694
1695     /* Generate authentication request event. */
1696     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1697         fgErrorKeyType));
1698
1699     /* If less than 60 seconds have passed since a previous TKIP MIC failure,
1700        disassociate from the AP and wait for 60 seconds before (re)associating
1701        with the same AP. */
1702     if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 &&
1703         !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime,
1704             prAisSpecBssInfo->u4RsnaLastMICFailTime,
1705             SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) {
1706         /* If less than 60 seconds expired since last MIC error, we have to
1707            block traffic. */
1708
1709         DBGLOG(RSN, INFO, ("Start blocking traffic!\n"));
1710         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1711
1712         secFsmEventStartCounterMeasure(prAdapter, prSta);
1713     }
1714     else {
1715         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1716         DBGLOG(RSN, INFO, ("First TKIP MIC error!\n"));
1717     }
1718
1719     COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime);
1720 #endif
1721 }   /* rsnTkipHandleMICFailure */
1722
1723
1724 /*----------------------------------------------------------------------------*/
1725 /*!
1726 * \brief This function is called to select a list of BSSID from
1727 *        the scan results for PMKID candidate list.
1728 *
1729 * \param[in] prBssDesc the BSS Desc at scan result list
1730 * \param[out] pu4CandidateCount Pointer to the number of selected candidates.
1731 *                         It is set to zero if no BSSID matches our requirement.
1732 *
1733 * \retval none
1734 */
1735 /*----------------------------------------------------------------------------*/
1736 VOID
1737 rsnSelectPmkidCandidateList (
1738     IN  P_ADAPTER_T       prAdapter,
1739     IN P_BSS_DESC_T       prBssDesc
1740     )
1741 {
1742     P_CONNECTION_SETTINGS_T prConnSettings;
1743     P_AIS_BSS_INFO_T      prAisBssInfo;
1744
1745     DEBUGFUNC("rsnSelectPmkidCandidateList");
1746
1747     ASSERT(prBssDesc);
1748
1749     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1750     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
1751
1752     /* Search a BSS with the same SSID from the given BSS description set. */
1753     //DBGLOG(RSN, TRACE, ("Check scan result ["MACSTR"]\n",
1754     //    MAC2STR(prBssDesc->aucBSSID)));
1755
1756     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1757                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1758         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1759         return;
1760     }
1761
1762 #if 0
1763     if ((prBssDesc->u2BSSBasicRateSet &
1764          ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) ||
1765         prBssDesc->fgIsUnknownBssBasicRate) {
1766         DBGLOG(RSN, TRACE, ("-- Rate set not matched\n"));
1767         return;
1768     }
1769
1770     if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher ||*/
1771         prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*||
1772         prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) {
1773         DBGLOG(RSN, TRACE, ("-- Encrypt status not matched for PMKID \n"));
1774         return;
1775     }
1776 #endif
1777
1778     rsnUpdatePmkidCandidateList(prAdapter, prBssDesc);
1779
1780 }   /* rsnSelectPmkidCandidateList */
1781
1782
1783 /*----------------------------------------------------------------------------*/
1784 /*!
1785 * \brief This function is called to select a list of BSSID from
1786 *        the scan results for PMKID candidate list.
1787 *
1788 * \param[in] prBssDesc the BSS DESC at scan result list
1789 *
1790 * \retval none
1791 */
1792 /*----------------------------------------------------------------------------*/
1793 VOID
1794 rsnUpdatePmkidCandidateList (
1795     IN  P_ADAPTER_T       prAdapter,
1796     IN  P_BSS_DESC_T      prBssDesc
1797     )
1798 {
1799     UINT_32                   i;
1800     P_CONNECTION_SETTINGS_T   prConnSettings;
1801     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1802
1803     DEBUGFUNC("rsnUpdatePmkidCandidateList");
1804
1805     ASSERT(prBssDesc);
1806
1807     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1808     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1809
1810     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1811                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1812         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1813         return;
1814     }
1815
1816     for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) {
1817         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))
1818             return;
1819     }
1820
1821     /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16),
1822        then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */
1823     if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1)  > CFG_MAX_PMKID_CACHE) {
1824         prAisSpecBssInfo->u4PmkidCandicateCount --;
1825     }
1826
1827     i = prAisSpecBssInfo->u4PmkidCandicateCount;
1828
1829     COPY_MAC_ADDR((PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1830         (PVOID)prBssDesc->aucBSSID);
1831
1832     if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) {
1833         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1;
1834         DBGLOG(RSN, TRACE, ("Add " MACSTR " with pre-auth to candidate list\n",
1835             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1836     }
1837     else {
1838         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0;
1839         DBGLOG(RSN, TRACE, ("Add " MACSTR " without pre-auth to candidate list\n",
1840             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1841     }
1842
1843     prAisSpecBssInfo->u4PmkidCandicateCount ++;
1844
1845 }   /* rsnUpdatePmkidCandidateList */
1846
1847
1848 /*----------------------------------------------------------------------------*/
1849 /*!
1850 * \brief This routine is called to search the desired entry in
1851 *        PMKID cache according to the BSSID
1852 *
1853 * \param[in] pucBssid Pointer to the BSSID
1854 * \param[out] pu4EntryIndex Pointer to place the found entry index
1855 *
1856 * \retval TRUE, if found one entry for specified BSSID
1857 * \retval FALSE, if not found
1858 */
1859 /*----------------------------------------------------------------------------*/
1860 BOOLEAN
1861 rsnSearchPmkidEntry (
1862     IN  P_ADAPTER_T       prAdapter,
1863     IN  PUINT_8           pucBssid,
1864     OUT PUINT_32          pu4EntryIndex
1865     )
1866 {
1867     UINT_32 i;
1868     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1869
1870     DEBUGFUNC("rsnSearchPmkidEntry");
1871
1872     ASSERT(pucBssid);
1873     ASSERT(pu4EntryIndex);
1874
1875     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1876
1877     if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) {
1878         return FALSE;
1879     }
1880
1881     ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE);
1882
1883     /* Search for desired BSSID */
1884     for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
1885         if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid,
1886             MAC_ADDR_LEN)) {
1887             break;
1888         }
1889     }
1890
1891     /* If desired BSSID is found, then set the PMKID */
1892     if (i < prAisSpecBssInfo->u4PmkidCacheCount) {
1893         *pu4EntryIndex = i;
1894
1895         return TRUE;
1896     }
1897
1898     return FALSE;
1899 }   /* rsnSearchPmkidEntry */
1900
1901
1902 /*----------------------------------------------------------------------------*/
1903 /*!
1904 * \brief This routine is called to check if there is difference
1905 *        between PMKID candicate list and PMKID cache. If there
1906 *        is new candicate that no cache entry is available, then
1907 *        add a new entry for the new candicate in the PMKID cache
1908 *        and set the PMKID indication flag to TRUE.
1909 *
1910 * \retval TRUE, if new member in the PMKID candicate list
1911 * \retval FALSe, if no new member in the PMKID candicate list
1912 */
1913 /*----------------------------------------------------------------------------*/
1914 BOOLEAN
1915 rsnCheckPmkidCandicate (
1916     IN  P_ADAPTER_T       prAdapter
1917    )
1918 {
1919     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
1920     UINT_32                    i; // Index for PMKID candicate
1921     UINT_32                    j; // Indix for PMKID cache
1922     BOOLEAN                    status = FALSE;
1923
1924     DEBUGFUNC("rsnCheckPmkidCandicate");
1925
1926     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1927
1928     /* Check for each candicate */
1929     for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) {
1930         for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) {
1931             if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
1932                     prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1933                     MAC_ADDR_LEN)) {
1934                 //DBGLOG(RSN, TRACE, (MACSTR" at PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1935                 break;
1936             }
1937         }
1938
1939         /* No entry found in PMKID cache for the candicate, add new one */
1940         if (j == prAisSpecBssInfo->u4PmkidCacheCount && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) {
1941             DBGLOG(RSN, TRACE, ("Add "MACSTR" to PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1942             kalMemCopy((PVOID)prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID,
1943                 (PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1944                 MAC_ADDR_LEN);
1945             prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE;
1946             prAisSpecBssInfo->u4PmkidCacheCount++;
1947
1948             status = TRUE;
1949         }
1950     }
1951
1952     return status;
1953 } /* rsnCheckPmkidCandicate */
1954
1955
1956 /*----------------------------------------------------------------------------*/
1957 /*!
1958 * \brief This function is called to wait a duration to indicate the pre-auth AP candicate
1959 *
1960 * \return (none)
1961 */
1962 /*----------------------------------------------------------------------------*/
1963 VOID
1964 rsnIndicatePmkidCand (
1965     IN  P_ADAPTER_T       prAdapter,
1966     IN  UINT_32           u4Parm
1967     )
1968 {
1969     DBGLOG(RSN, EVENT, ("Security - Time to indicate the PMKID cand.\n"));
1970
1971     /* If the authentication mode is WPA2 and indication PMKID flag
1972        is available, then we indicate the PMKID candidate list to NDIS and
1973        clear the flag, indicatePMKID */
1974
1975     if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
1976         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1977         rsnGeneratePmkidIndication(prAdapter);
1978     }
1979
1980     return;
1981 } /* end of rsnIndicatePmkidCand() */
1982
1983
1984 /*----------------------------------------------------------------------------*/
1985 /*!
1986 * \brief This routine is called to check the BSS Desc at scan result
1987 *             with pre-auth cap at wpa2 mode. If there
1988 *             is candicate that no cache entry is available, then
1989 *             add a new entry for the new candicate in the PMKID cache
1990 *             and set the PMKID indication flag to TRUE.
1991 *
1992 * \param[in] prBss The BSS Desc at scan result
1993 *
1994 * \return none
1995 */
1996 /*----------------------------------------------------------------------------*/
1997 VOID
1998 rsnCheckPmkidCache (
1999     IN  P_ADAPTER_T       prAdapter,
2000     IN  P_BSS_DESC_T      prBss
2001     )
2002 {
2003     P_AIS_BSS_INFO_T           prAisBssInfo;
2004     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
2005     P_CONNECTION_SETTINGS_T    prConnSettings;
2006
2007     DEBUGFUNC("rsnCheckPmkidCandicate");
2008
2009     ASSERT(prBss);
2010
2011     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
2012     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2013     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2014
2015     if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&
2016        (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) {
2017         rsnSelectPmkidCandidateList(prAdapter, prBss);
2018
2019         /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection()
2020            will indicate this later */
2021         if (rsnCheckPmkidCandicate(prAdapter)) {
2022             DBGLOG(RSN, TRACE, ("Prepare a timer to indicate candidate PMKID Candidate\n"));
2023             cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
2024             cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
2025                     SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2026         }
2027     }
2028 }
2029
2030
2031 /*----------------------------------------------------------------------------*/
2032 /*!
2033 * \brief This routine is called to generate an PMKID candidate list
2034 *        indication to NDIS.
2035 *
2036 * \param[in] prAdapter Pointer to the adapter object data area.
2037 * \param[in] u4Flags PMKID candidate list event:
2038 *                    PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
2039 *
2040 * \retval none
2041 */
2042 /*----------------------------------------------------------------------------*/
2043 VOID
2044 rsnGeneratePmkidIndication (
2045     IN  P_ADAPTER_T       prAdapter
2046     )
2047 {
2048     P_PARAM_STATUS_INDICATION_T    prStatusEvent;
2049     P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent;
2050     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
2051     UINT_8                i, j = 0, count = 0;
2052     UINT_32               u4LenOfUsedBuffer;
2053
2054     DEBUGFUNC("rsnGeneratePmkidIndication");
2055
2056     ASSERT(prAdapter);
2057
2058     prStatusEvent =
2059         (P_PARAM_STATUS_INDICATION_T)prAdapter->aucIndicationEventBuffer;
2060
2061     /* Status type: PMKID Candidatelist Event */
2062     prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
2063     ASSERT(prStatusEvent);
2064
2065     prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T)(&prStatusEvent->eStatusType + 1);
2066     ASSERT(prPmkidEvent);
2067
2068     prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2069     ASSERT(prAisSpecificBssInfo);
2070
2071     for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) {
2072         for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) {
2073             if (EQUAL_MAC_ADDR( prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
2074                 prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) &&
2075                 (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)){
2076                 break;
2077             }
2078         }
2079         if (count >= CFG_MAX_PMKID_CACHE) {
2080             break;
2081         }
2082
2083         if (j == prAisSpecificBssInfo->u4PmkidCacheCount) {
2084             kalMemCopy((PVOID)prPmkidEvent->arCandidateList[count].arBSSID,
2085                 (PVOID)prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid,
2086                 PARAM_MAC_ADDR_LEN);
2087             prPmkidEvent->arCandidateList[count].u4Flags =
2088                 prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags;
2089             DBGLOG(RSN, TRACE, (MACSTR" %d\n", MAC2STR(prPmkidEvent->arCandidateList[count].arBSSID),
2090                 prPmkidEvent->arCandidateList[count].u4Flags));
2091             count++;
2092         }
2093     }
2094
2095     /* PMKID Candidate List */
2096     prPmkidEvent->u4Version = 1;
2097     prPmkidEvent->u4NumCandidates = count;
2098     DBGLOG(RSN, TRACE, ("rsnGeneratePmkidIndication #%d\n", prPmkidEvent->u4NumCandidates));
2099     u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) +
2100         (count * sizeof(PARAM_PMKID_CANDIDATE_T));
2101     //dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer);
2102
2103     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2104         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
2105         (PVOID) prAdapter->aucIndicationEventBuffer,
2106         u4LenOfUsedBuffer);
2107
2108 }   /* rsnGeneratePmkidIndication */
2109 #endif
2110
2111 #if CFG_SUPPORT_WPS2
2112 /*----------------------------------------------------------------------------*/
2113 /*!
2114 *
2115 * \brief This routine is called to generate WSC IE for
2116 *        associate request frame.
2117 *
2118 * \param[in]  prCurrentBss     The Selected BSS description
2119 *
2120 * \retval The append WSC IE length
2121 *
2122 * \note
2123 *      Called by: AIS module, Associate request
2124 */
2125 /*----------------------------------------------------------------------------*/
2126 VOID
2127 rsnGenerateWSCIE (
2128     IN P_ADAPTER_T          prAdapter,
2129     IN P_MSDU_INFO_T        prMsduInfo
2130     )
2131 {
2132     PUINT_8                 pucBuffer;
2133
2134     ASSERT(prAdapter);
2135     ASSERT(prMsduInfo);
2136
2137     if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
2138         return;
2139
2140     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
2141                           (UINT_32)prMsduInfo->u2FrameLength);
2142
2143     /* ASSOC INFO IE ID: 221 :0xDD */
2144     if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) {
2145         kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, prAdapter->prGlueInfo->u2WSCAssocInfoIELen);
2146         prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen;
2147     }
2148
2149 }
2150 #endif
2151
2152
2153 #if CFG_SUPPORT_802_11W
2154
2155 /*----------------------------------------------------------------------------*/
2156 /*!
2157 * \brief to check if the Bip Key installed or not
2158 *
2159 * \param[in]
2160 *           prAdapter
2161 *
2162 * \return
2163 *           TRUE
2164 *           FALSE
2165 */
2166 /*----------------------------------------------------------------------------*/
2167 UINT_32
2168 rsnCheckBipKeyInstalled (
2169     IN P_ADAPTER_T                  prAdapter,
2170     IN P_STA_RECORD_T               prStaRec
2171     )
2172 {
2173     if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8)NETWORK_TYPE_AIS_INDEX)
2174         return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
2175     else
2176         return FALSE;
2177 }
2178
2179 /*----------------------------------------------------------------------------*/
2180 /*!
2181 *
2182 * \brief This routine is called to check the Sa query timeout.
2183 *
2184 *
2185 * \note
2186 *      Called by: AIS module, Handle by Sa Quert timeout
2187 */
2188 /*----------------------------------------------------------------------------*/
2189 UINT_8
2190 rsnCheckSaQueryTimeout (
2191     IN P_ADAPTER_T                  prAdapter
2192     )
2193 {
2194     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2195     UINT_32 now;
2196
2197     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2198     ASSERT(prBssSpecInfo);
2199
2200     GET_CURRENT_SYSTIME(&now);
2201
2202     if (CHECK_FOR_TIMEOUT(now,
2203                 prBssSpecInfo->u4SaQueryStart,
2204                 TU_TO_MSEC(1000))) {
2205         LOG_FUNC("association SA Query timed out\n");
2206
2207         prBssSpecInfo->ucSaQueryTimedOut = 1;
2208         kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2209         prBssSpecInfo->pucSaQueryTransId = NULL;
2210         prBssSpecInfo->u4SaQueryCount = 0;
2211         cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2212         /* Re-connect */
2213         kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2214                 WLAN_STATUS_MEDIA_DISCONNECT,
2215                 NULL,
2216                 0);
2217
2218         return 1;
2219     }
2220
2221     return 0;
2222 }
2223
2224 /*----------------------------------------------------------------------------*/
2225 /*!
2226 *
2227 * \brief This routine is called to start the 802.11w sa query timer.
2228 *
2229 *
2230 * \note
2231 *      Called by: AIS module, Handle Rx mgmt request
2232 */
2233 /*----------------------------------------------------------------------------*/
2234 void rsnStartSaQueryTimer (
2235     IN P_ADAPTER_T                  prAdapter
2236     )
2237 {
2238     P_BSS_INFO_T                    prBssInfo;
2239     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2240     P_MSDU_INFO_T                   prMsduInfo;
2241     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2242     UINT_16                         u2PayloadLen;
2243     PUINT_8                         pucTmp = NULL;
2244     UINT_8                          ucTransId[ACTION_SA_QUERY_TR_ID_LEN];
2245
2246     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2247     ASSERT(prBssInfo);
2248
2249     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2250     ASSERT(prBssSpecInfo);
2251
2252     LOG_FUNC("MFP: Start Sa Query\n");
2253
2254     if (prBssSpecInfo->u4SaQueryCount > 0 &&
2255         rsnCheckSaQueryTimeout(prAdapter)) {
2256         LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount);
2257         return;
2258     }
2259
2260     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2261                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2262
2263     if (!prMsduInfo)
2264         return;
2265
2266     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2267         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2268
2269     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2270     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2271
2272     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2273     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2274     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2275
2276     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2277     prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
2278
2279     if (prBssSpecInfo->u4SaQueryCount == 0) {
2280         GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart);
2281     }
2282
2283     if (prBssSpecInfo->u4SaQueryCount) {
2284         pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2285         if (!pucTmp) {
2286             DBGLOG(RSN, INFO, ("MFP: Fail to alloc tmp buffer for backup sa query id\n"));
2287             return;
2288         }
2289         kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2290     }
2291
2292     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2293
2294     ucTransId[0] = (UINT_8)(kalRandomNumber() & 0xFF);
2295     ucTransId[1] = (UINT_8)(kalRandomNumber() & 0xFF);
2296
2297     kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2298
2299     prBssSpecInfo->u4SaQueryCount++;
2300
2301     prBssSpecInfo->pucSaQueryTransId = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2302     if (!prBssSpecInfo->pucSaQueryTransId) {
2303         DBGLOG(RSN, INFO, ("MFP: Fail to alloc buffer for sa query id list\n"));
2304         return;
2305     }
2306
2307     if (pucTmp) {
2308         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2309         kalMemCopy(&prBssSpecInfo->pucSaQueryTransId[(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN],
2310             ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2311         kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2312     }
2313     else {
2314         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2315     }
2316
2317     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2318
2319     //4 Update information of MSDU_INFO_T
2320     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2321     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2322     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2323     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2324     prMsduInfo->fgIs802_1x = FALSE;
2325     prMsduInfo->fgIs802_11 = TRUE;
2326     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2327     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2328     prMsduInfo->pfTxDoneHandler = NULL;
2329     prMsduInfo->fgIsBasicRate = FALSE;
2330
2331     //4 Enqueue the frame to send this action frame.
2332     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2333
2334     DBGLOG(RSN, TRACE, ("Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval));
2335
2336     cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer,
2337         TU_TO_MSEC(201));
2338
2339 }
2340
2341
2342 /*----------------------------------------------------------------------------*/
2343 /*!
2344 *
2345 * \brief This routine is called to start the 802.11w sa query.
2346 *
2347 *
2348 * \note
2349 *      Called by: AIS module, Handle Rx mgmt request
2350 */
2351 /*----------------------------------------------------------------------------*/
2352 void rsnStartSaQuery (
2353     IN P_ADAPTER_T                  prAdapter
2354     )
2355 {
2356     rsnStartSaQueryTimer(prAdapter);
2357 }
2358
2359
2360 /*----------------------------------------------------------------------------*/
2361 /*!
2362 *
2363 * \brief This routine is called to stop the 802.11w sa query.
2364 *
2365 *
2366 * \note
2367 *      Called by: AIS module, Handle Rx mgmt request
2368 */
2369 /*----------------------------------------------------------------------------*/
2370 void rsnStopSaQuery (
2371     IN P_ADAPTER_T                  prAdapter
2372     )
2373 {
2374     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2375
2376     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2377     ASSERT(prBssSpecInfo);
2378
2379     cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2380     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2381     prBssSpecInfo->pucSaQueryTransId = NULL;
2382     prBssSpecInfo->u4SaQueryCount = 0;
2383 }
2384
2385 /*----------------------------------------------------------------------------*/
2386 /*!
2387 *
2388 * \brief This routine is called to process the 802.11w sa query action frame.
2389 *
2390 *
2391 * \note
2392 *      Called by: AIS module, Handle Rx mgmt request
2393 */
2394 /*----------------------------------------------------------------------------*/
2395 void
2396 rsnSaQueryRequest (
2397     IN P_ADAPTER_T                  prAdapter,
2398     IN P_SW_RFB_T                   prSwRfb
2399     )
2400 {
2401     P_BSS_INFO_T                    prBssInfo;
2402     P_MSDU_INFO_T                   prMsduInfo;
2403     P_ACTION_SA_QUERY_FRAME         prRxFrame = NULL;
2404     UINT_16                         u2PayloadLen;
2405     P_STA_RECORD_T                  prStaRec;
2406     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2407
2408     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2409     ASSERT(prBssInfo);
2410
2411     prRxFrame = (P_ACTION_SA_QUERY_FRAME)prSwRfb->pvHeader;
2412     if (!prRxFrame)
2413         return;
2414
2415     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2416
2417     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Request from "
2418            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2419
2420     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2421             ACTION_SA_QUERY_TR_ID_LEN);
2422
2423     if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
2424         DBGLOG(RSN, TRACE, ("IEEE 802.11: Ignore SA Query Request "
2425                "from unassociated STA " MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2426         return;
2427     }
2428     DBGLOG(RSN, TRACE, ("IEEE 802.11: Sending SA Query Response to "
2429            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2430
2431     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2432                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2433
2434     if (!prMsduInfo)
2435         return;
2436
2437     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2438         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2439
2440     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2441     /* SA Query always with protected */
2442     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2443
2444     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2445     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2446     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2447
2448     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2449     prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
2450
2451     kalMemCopy(prTxFrame->ucTransId,
2452           prRxFrame->ucTransId,
2453           ACTION_SA_QUERY_TR_ID_LEN);
2454
2455     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2456
2457     //4 Update information of MSDU_INFO_T
2458     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2459     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2460     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2461     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2462     prMsduInfo->fgIs802_1x = FALSE;
2463     prMsduInfo->fgIs802_11 = TRUE;
2464     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2465     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2466     prMsduInfo->pfTxDoneHandler = NULL;
2467     prMsduInfo->fgIsBasicRate = FALSE;
2468
2469     //4 Enqueue the frame to send this action frame.
2470     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2471
2472 }
2473
2474
2475 /*----------------------------------------------------------------------------*/
2476 /*!
2477 *
2478 * \brief This routine is called to process the 802.11w sa query action frame.
2479 *
2480 *
2481 * \note
2482 *      Called by: AIS module, Handle Rx mgmt request
2483 */
2484 /*----------------------------------------------------------------------------*/
2485 void
2486 rsnSaQueryAction (
2487     IN P_ADAPTER_T                  prAdapter,
2488     IN P_SW_RFB_T                   prSwRfb
2489     )
2490 {
2491     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2492     P_ACTION_SA_QUERY_FRAME         prRxFrame;
2493     P_STA_RECORD_T                  prStaRec;
2494     UINT_32                         i;
2495
2496     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2497     ASSERT(prBssSpecInfo);
2498
2499     prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
2500     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2501
2502     if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
2503         DBGLOG(RSN, TRACE, ("IEEE 802.11: Too short SA Query Action "
2504                "frame (len=%lu)\n", (unsigned long) prSwRfb->u2PacketLen));
2505         return;
2506     }
2507
2508     if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
2509         rsnSaQueryRequest(prAdapter, prSwRfb);
2510         return;
2511     }
2512
2513     if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
2514         DBGLOG(RSN, TRACE, ("IEEE 802.11: Unexpected SA Query "
2515                "Action %d\n", prRxFrame->ucAction));
2516         return;
2517     }
2518
2519     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Response from "
2520            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2521
2522     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2523            ACTION_SA_QUERY_TR_ID_LEN);
2524
2525     /* MLME-SAQuery.confirm */
2526
2527     for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) {
2528         if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId +
2529                   i * ACTION_SA_QUERY_TR_ID_LEN,
2530                   prRxFrame->ucTransId,
2531                   ACTION_SA_QUERY_TR_ID_LEN) == 0)
2532             break;
2533     }
2534
2535     if (i >= prBssSpecInfo->u4SaQueryCount) {
2536         DBGLOG(RSN, TRACE, ("IEEE 802.11: No matching SA Query "
2537                "transaction identifier found\n"));
2538         return;
2539     }
2540
2541     DBGLOG(RSN, TRACE, ("Reply to pending SA Query received\n"));
2542
2543     rsnStopSaQuery(prAdapter);
2544 }
2545
2546
2547 /*----------------------------------------------------------------------------*/
2548 /*!
2549 *
2550 * \brief This routine is called to process the 802.11w mgmt frame.
2551 *
2552 *
2553 * \note
2554 *      Called by: AIS module, Handle Rx mgmt request
2555 */
2556 /*----------------------------------------------------------------------------*/
2557 BOOLEAN
2558 rsnCheckRxMgmt (
2559     IN P_ADAPTER_T                  prAdapter,
2560     IN P_SW_RFB_T                   prSwRfb,
2561     IN UINT_8                       ucSubtype
2562     )
2563 {
2564     P_HIF_RX_HEADER_T               prHifRxHdr;
2565     BOOLEAN                         fgUnicast = TRUE;
2566     BOOLEAN                         fgRobustAction = FALSE;
2567
2568     prHifRxHdr = prSwRfb->prHifRxHdr;
2569
2570     if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) &&
2571         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection  /* Use MFP */) {
2572
2573         P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
2574         prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
2575
2576         if (prAssocReqFrame->aucDestAddr[0] & BIT(0))
2577             fgUnicast = FALSE;
2578
2579         LOG_FUNC("QM RX MGT: rsnCheckRxMgmt = %d 0x%x %d ucSubtype=%x\n", fgUnicast, prHifRxHdr->ucReserved, (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC), ucSubtype);
2580
2581         if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) {
2582             /* "Dropped unprotected Robust Action frame from an MFP STA" */
2583             /* exclude Public Action */
2584             if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */)
2585             {
2586                 UINT_8 ucAction = *prSwRfb->pucRecvBuff;
2587                 if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) {
2588 #if DBG && CFG_RX_PKTS_DUMP
2589                     LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction);
2590 #endif
2591                     fgRobustAction = TRUE;
2592                     return TRUE;
2593                 }
2594             }
2595             if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) {
2596                 LOG_FUNC("QM RX MGT: rsnStartSaQuery\n");
2597                 /* MFP test plan 5.3.3.5 */
2598                 rsnStartSaQuery(prAdapter);
2599                 return TRUE;
2600             }
2601         }
2602 #if 0
2603         else {
2604             if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) {
2605                 /* This done by function handler */
2606                 //kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2607                 //      WLAN_STATUS_MEDIA_DISCONNECT,
2608                 //      NULL,
2609                 //      0);
2610             }
2611         }
2612 #endif
2613     }
2614     return FALSE;
2615 }
2616 #endif
2617