add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / combo_mt66xx / mt6620 / wlan / 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 * \brief Whether BSS RSN is matched from upper layer set.
746 *
747 * \param[in] prAdapter Pointer to the Adapter structure, BSS RSN Information
748 *
749 * \retval BOOLEAN
750 */
751 /*----------------------------------------------------------------------------*/
752 BOOLEAN
753 rsnIsSuitableBSS (
754     IN P_ADAPTER_T          prAdapter,
755     IN P_RSN_INFO_T         prBssRsnInfo
756     )
757 {
758     UINT_8 i = 0;
759
760     DEBUGFUNC("rsnIsSuitableBSS");
761
762     do{
763
764         if((prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite & 0x000000FF) != \
765             GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite)){
766             DBGLOG(RSN, TRACE, ("Break by GroupKeyCipherSuite\n"));
767             break;
768         }
769         for(i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++){
770             if(((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] & 0x000000FF) != \
771                 GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i]))
772                 && (i == prBssRsnInfo->u4PairwiseKeyCipherSuiteCount - 1) ){
773                 DBGLOG(RSN, TRACE, ("Break by PairwiseKeyCipherSuite\n"));
774                 break;
775             }
776         }
777         for(i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++){
778             if(((prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] & 0x000000FF) != \
779                 GET_SELECTOR_TYPE(prBssRsnInfo->au4AuthKeyMgtSuite[0]))
780                 && (i == prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1)){
781                 DBGLOG(RSN, TRACE, ("Break by AuthKeyMgtSuite \n"));
782                 break;
783             }
784         }
785             return TRUE;
786         }while(FALSE);
787     return FALSE;
788 }
789
790
791
792 /*----------------------------------------------------------------------------*/
793 /*!
794 *
795 * \brief This routine is called to search the desired
796 *        authentication and key management (AKM) suite from the
797 *        MIB Authentication and Key Management Suites table.
798 *
799 * \param[in]  u4AkmSuite The desired AKM suite to be searched
800 * \param[out] pu4Index   Pointer to the index of the desired AKM suite in the
801 *                        table
802 *
803 * \retval TRUE  The desired AKM suite is found in the table.
804 * \retval FALSE The desired AKM suite is not found in the table.
805 *
806 * \note
807 */
808 /*----------------------------------------------------------------------------*/
809 BOOLEAN
810 rsnSearchAKMSuite (
811     IN  P_ADAPTER_T       prAdapter,
812     IN  UINT_32           u4AkmSuite,
813     OUT PUINT_32          pu4Index
814     )
815 {
816     UINT_8 i;
817     P_DOT11_RSNA_CONFIG_AUTHENTICATION_SUITES_ENTRY prEntry;
818
819     DEBUGFUNC("rsnSearchAKMSuite");
820
821     ASSERT(pu4Index);
822
823     for (i = 0; i < MAX_NUM_SUPPORTED_AKM_SUITES; i++) {
824         prEntry = &prAdapter->rMib.dot11RSNAConfigAuthenticationSuitesTable[i];
825         if (prEntry->dot11RSNAConfigAuthenticationSuite == u4AkmSuite &&
826             prEntry->dot11RSNAConfigAuthenticationSuiteEnabled) {
827             *pu4Index = i;
828             return TRUE;
829         }
830     }
831     return FALSE;
832 }   /* rsnSearchAKMSuite */
833
834
835 /*----------------------------------------------------------------------------*/
836 /*!
837 * \brief This routine is called to perform RSNA or TSN policy
838 *        selection for a given BSS.
839 *
840 * \param[in]  prBss Pointer to the BSS description
841 *
842 * \retval TRUE - The RSNA/TSN policy selection for the given BSS is
843 *                successful. The selected pairwise and group cipher suites
844 *                are returned in the BSS description.
845 * \retval FALSE - The RSNA/TSN policy selection for the given BSS is failed.
846 *                 The driver shall not attempt to join the given BSS.
847 *
848 * \note The Encrypt status matched score will save to bss for final ap select.
849 */
850 /*----------------------------------------------------------------------------*/
851 BOOLEAN
852 rsnPerformPolicySelection (
853     IN  P_ADAPTER_T         prAdapter,
854     IN  P_BSS_DESC_T        prBss
855     )
856 {
857 #if CFG_SUPPORT_802_11W
858     INT_32                  i;
859     UINT_32                 j;
860 #else
861     UINT_32                 i, j;
862 #endif
863     BOOLEAN                 fgSuiteSupported;
864     UINT_32                 u4PairwiseCipher = 0;
865     UINT_32                 u4GroupCipher = 0;
866     UINT_32                 u4AkmSuite = 0;
867     P_RSN_INFO_T            prBssRsnInfo;
868     ENUM_NETWORK_TYPE_INDEX_T eNetwotkType;
869     BOOLEAN                 fgIsWpsActive = (BOOLEAN)FALSE;
870
871     DEBUGFUNC("rsnPerformPolicySelection");
872
873     ASSERT(prBss);
874
875     DBGLOG(RSN, TRACE, ("rsnPerformPolicySelection\n"));
876     //Todo::
877     eNetwotkType = NETWORK_TYPE_AIS_INDEX;
878
879     prBss->u4RsnSelectedPairwiseCipher = 0;
880     prBss->u4RsnSelectedGroupCipher = 0;
881     prBss->u4RsnSelectedAKMSuite = 0;
882     prBss->ucEncLevel = 0;
883
884 #if CFG_SUPPORT_WPS
885     fgIsWpsActive = kalWSCGetActiveState(prAdapter->prGlueInfo);
886
887     /* CR1640, disable the AP select privacy check */
888     if ( fgIsWpsActive &&
889         (prAdapter->rWifiVar.rConnSettings.eAuthMode < AUTH_MODE_WPA) &&
890         (prAdapter->rWifiVar.rConnSettings.eOPMode == NET_TYPE_INFRA)) {
891         DBGLOG(RSN, TRACE,("-- Skip the Protected BSS check\n"));
892         return TRUE;
893     }
894 #endif
895
896     /* Protection is not required in this BSS. */
897     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) == 0 ) {
898
899         if (secEnabledInAis(prAdapter) == FALSE) {
900             DBGLOG(RSN, TRACE,("-- No Protected BSS\n"));
901             return TRUE;
902         }
903         else {
904             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
905             return FALSE;
906         }
907     }
908
909     /* Protection is required in this BSS. */
910     if ((prBss->u2CapInfo & CAP_INFO_PRIVACY) != 0) {
911         if (secEnabledInAis(prAdapter) == FALSE) {
912             DBGLOG(RSN, TRACE,("-- Protected BSS\n"));
913             return FALSE;
914         }
915     }
916
917     if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA ||
918         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK ||
919         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_NONE) {
920
921         if (prBss->fgIEWPA) {
922             prBssRsnInfo = &prBss->rWPAInfo;
923         }
924         else {
925             DBGLOG(RSN, TRACE, ("WPA Information Element does not exist.\n"));
926             return FALSE;
927         }
928     }
929     else if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2 ||
930         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK) {
931
932         if (prBss->fgIERSN) {
933             prBssRsnInfo = &prBss->rRSNInfo;
934         }
935         else {
936             DBGLOG(RSN, TRACE, ("RSN Information Element does not exist.\n"));
937             return FALSE;
938         }
939     }
940     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus != ENUM_ENCRYPTION1_ENABLED) {
941         /* If the driver is configured to use WEP only, ignore this BSS. */
942         DBGLOG(RSN, TRACE, ("-- Not WEP-only legacy BSS\n"));
943         return FALSE;
944     }
945     else if (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION1_ENABLED) {
946         /* If the driver is configured to use WEP only, use this BSS. */
947         DBGLOG(RSN, TRACE, ("-- WEP-only legacy BSS\n"));
948         return TRUE;
949     }
950
951     if(!rsnIsSuitableBSS(prAdapter, prBssRsnInfo))
952      {
953         DBGLOG(RSN, TRACE, ("RSN info check no matched\n"));
954         return FALSE;
955      }
956
957     if (prBssRsnInfo->u4PairwiseKeyCipherSuiteCount == 1 &&
958         GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[0]) ==
959         CIPHER_SUITE_NONE) {
960         /* Since the pairwise cipher use the same cipher suite as the group
961            cipher in the BSS, we check the group cipher suite against the
962            current encryption status. */
963         fgSuiteSupported = FALSE;
964
965         switch (prBssRsnInfo->u4GroupKeyCipherSuite) {
966         case WPA_CIPHER_SUITE_CCMP:
967         case RSN_CIPHER_SUITE_CCMP:
968              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
969                  ENUM_ENCRYPTION3_ENABLED) {
970                  fgSuiteSupported = TRUE;
971              }
972              break;
973
974         case WPA_CIPHER_SUITE_TKIP:
975         case RSN_CIPHER_SUITE_TKIP:
976              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
977                  ENUM_ENCRYPTION2_ENABLED) {
978                  fgSuiteSupported = TRUE;
979              }
980              break;
981
982         case WPA_CIPHER_SUITE_WEP40:
983         case WPA_CIPHER_SUITE_WEP104:
984              if (prAdapter->rWifiVar.rConnSettings.eEncStatus ==
985                  ENUM_ENCRYPTION1_ENABLED) {
986                  fgSuiteSupported = TRUE;
987              }
988              break;
989         }
990
991         if (fgSuiteSupported) {
992             u4PairwiseCipher = WPA_CIPHER_SUITE_NONE;
993             u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
994         }
995 #if DBG
996         else {
997             DBGLOG(RSN, TRACE, ("Inproper encryption status %d for group-key-only BSS\n",
998                 prAdapter->rWifiVar.rConnSettings.eEncStatus));
999         }
1000 #endif
1001     }
1002     else {
1003         fgSuiteSupported = FALSE;
1004
1005         DBGLOG(RSN, TRACE, ("eEncStatus %d %d 0x%x\n", prAdapter->rWifiVar.rConnSettings.eEncStatus,
1006             prBssRsnInfo->u4PairwiseKeyCipherSuiteCount,
1007             prBssRsnInfo->au4PairwiseKeyCipherSuite[0]));
1008         /* Select pairwise/group ciphers */
1009         switch (prAdapter->rWifiVar.rConnSettings.eEncStatus)
1010         {
1011         case ENUM_ENCRYPTION3_ENABLED:
1012              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1013                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1014                      == CIPHER_SUITE_CCMP) {
1015                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1016                  }
1017              }
1018              u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1019              break;
1020
1021         case ENUM_ENCRYPTION2_ENABLED:
1022              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1023                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1024                      == CIPHER_SUITE_TKIP) {
1025                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1026                  }
1027              }
1028              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1029                  CIPHER_SUITE_CCMP) {
1030                  DBGLOG(RSN, TRACE, ("Cannot join CCMP BSS\n"));
1031              }
1032              else {
1033                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1034              }
1035              break;
1036
1037         case ENUM_ENCRYPTION1_ENABLED:
1038              for (i = 0; i < prBssRsnInfo->u4PairwiseKeyCipherSuiteCount; i++) {
1039                  if (GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1040                      == CIPHER_SUITE_WEP40 ||
1041                      GET_SELECTOR_TYPE(prBssRsnInfo->au4PairwiseKeyCipherSuite[i])
1042                      == CIPHER_SUITE_WEP104) {
1043                      u4PairwiseCipher = prBssRsnInfo->au4PairwiseKeyCipherSuite[i];
1044                  }
1045              }
1046              if (GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1047                  CIPHER_SUITE_CCMP ||
1048                  GET_SELECTOR_TYPE(prBssRsnInfo->u4GroupKeyCipherSuite) ==
1049                  CIPHER_SUITE_TKIP) {
1050                  DBGLOG(RSN, TRACE, ("Cannot join CCMP/TKIP BSS\n"));
1051              }
1052              else {
1053                  u4GroupCipher = prBssRsnInfo->u4GroupKeyCipherSuite;
1054              }
1055              break;
1056
1057         default:
1058              break;
1059         }
1060     }
1061
1062     /* Exception handler */
1063     /* If we cannot find proper pairwise and group cipher suites to join the
1064        BSS, do not check the supported AKM suites. */
1065     if (u4PairwiseCipher == 0 || u4GroupCipher == 0) {
1066         DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher (0x%08lx/0x%08lx)\n",
1067             u4PairwiseCipher, u4GroupCipher));
1068         return FALSE;
1069     }
1070
1071 #if CFG_ENABLE_WIFI_DIRECT
1072     if ((prAdapter->fgIsP2PRegistered) &&
1073         (eNetwotkType == NETWORK_TYPE_P2P_INDEX)) {
1074         if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1075             u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1076             u4AkmSuite != RSN_AKM_SUITE_PSK) {
1077             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for P2P network (0x%08lx/0x%08lx)\n",
1078                 u4PairwiseCipher, u4GroupCipher));
1079             return FALSE;
1080         }
1081     }
1082 #endif
1083
1084 #if CFG_ENABLE_BT_OVER_WIFI
1085         if (eNetwotkType == NETWORK_TYPE_BOW_INDEX) {
1086             if (u4PairwiseCipher != RSN_CIPHER_SUITE_CCMP ||
1087                 u4GroupCipher != RSN_CIPHER_SUITE_CCMP ||
1088                 u4AkmSuite != RSN_AKM_SUITE_PSK) {
1089             }
1090             DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08lx/0x%08lx)\n",
1091                 u4PairwiseCipher, u4GroupCipher));
1092             return FALSE;
1093         }
1094 #endif
1095
1096
1097     /* Verify if selected pairwisse cipher is supported */
1098     fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4PairwiseCipher, &i);
1099
1100     /* Verify if selected group cipher is supported */
1101     if (fgSuiteSupported) {
1102         fgSuiteSupported = rsnSearchSupportedCipher(prAdapter, u4GroupCipher, &i);
1103     }
1104
1105     if (!fgSuiteSupported) {
1106         DBGLOG(RSN, TRACE, ("Failed to support selected pairwise/group cipher (0x%08lx/0x%08lx)\n",
1107             u4PairwiseCipher, u4GroupCipher));
1108         return FALSE;
1109     }
1110
1111     /* Select AKM */
1112     /* If the driver cannot support any authentication suites advertised in
1113        the given BSS, we fail to perform RSNA policy selection. */
1114     /* Attempt to find any overlapping supported AKM suite. */
1115 #if CFG_SUPPORT_802_11W
1116     if (i != 0)
1117         for (i = (prBssRsnInfo->u4AuthKeyMgtSuiteCount - 1); i >= 0; i--)
1118 #else
1119     for (i = 0; i < prBssRsnInfo->u4AuthKeyMgtSuiteCount; i++)
1120 #endif
1121     {
1122         if (rsnSearchAKMSuite(prAdapter,
1123             prBssRsnInfo->au4AuthKeyMgtSuite[i],
1124             &j)) {
1125             u4AkmSuite = prBssRsnInfo->au4AuthKeyMgtSuite[i];
1126             break;
1127         }
1128     }
1129
1130     if (u4AkmSuite == 0) {
1131         DBGLOG(RSN, TRACE, ("Cannot support any AKM suites\n"));
1132         return FALSE;
1133     }
1134
1135     DBGLOG(RSN, TRACE, ("Selected pairwise/group cipher: %02x-%02x-%02x-%02x/%02x-%02x-%02x-%02x\n",
1136         (UINT_8) (u4PairwiseCipher & 0x000000FF),
1137         (UINT_8) ((u4PairwiseCipher >> 8) & 0x000000FF),
1138         (UINT_8) ((u4PairwiseCipher >> 16) & 0x000000FF),
1139         (UINT_8) ((u4PairwiseCipher >> 24) & 0x000000FF),
1140         (UINT_8) (u4GroupCipher & 0x000000FF),
1141         (UINT_8) ((u4GroupCipher >> 8) & 0x000000FF),
1142         (UINT_8) ((u4GroupCipher >> 16) & 0x000000FF),
1143         (UINT_8) ((u4GroupCipher >> 24) & 0x000000FF)));
1144
1145     DBGLOG(RSN, TRACE, ("Selected AKM suite: %02x-%02x-%02x-%02x\n",
1146         (UINT_8) (u4AkmSuite & 0x000000FF),
1147         (UINT_8) ((u4AkmSuite >> 8) & 0x000000FF),
1148         (UINT_8) ((u4AkmSuite >> 16) & 0x000000FF),
1149         (UINT_8) ((u4AkmSuite >> 24) & 0x000000FF)));
1150
1151 #if CFG_SUPPORT_802_11W
1152     DBGLOG(RSN, TRACE, ("MFP setting = %d\n ", kalGetMfpSetting(prAdapter->prGlueInfo)));
1153
1154     if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1155         if (!prBssRsnInfo->fgRsnCapPresent) {
1156             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability.\n"));
1157             return FALSE;
1158         }
1159         else if (!(prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC)) {
1160             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required\n"));
1161             return FALSE;
1162         }
1163         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1164     }
1165     else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1166         if (prBssRsnInfo->u2RsnCap && ((prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR) ||
1167             (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPC))) {
1168             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = TRUE;
1169         }
1170         else {
1171             prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1172         }
1173     }
1174     else {
1175         if (prBssRsnInfo->fgRsnCapPresent && (prBssRsnInfo->u2RsnCap & ELEM_WPA_CAP_MFPR)) {
1176             DBGLOG(RSN, TRACE, ("Skip RSN IE, No MFP Required Capability\n"));
1177             return FALSE;
1178         }
1179         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection = FALSE;
1180     }
1181     DBGLOG(RSN, TRACE, ("fgMgmtProtection = %d\n ", prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection));
1182 #endif
1183
1184     if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_CCMP){
1185         prBss->ucEncLevel = 3;
1186     }
1187     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_TKIP){
1188         prBss->ucEncLevel = 2;
1189     }
1190     else if (GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP40 ||
1191         GET_SELECTOR_TYPE(u4GroupCipher) == CIPHER_SUITE_WEP104) {
1192         prBss->ucEncLevel = 1;
1193     }
1194     else {
1195         ASSERT(FALSE);
1196     }
1197     prBss->u4RsnSelectedPairwiseCipher = u4PairwiseCipher;
1198     prBss->u4RsnSelectedGroupCipher = u4GroupCipher;
1199     prBss->u4RsnSelectedAKMSuite = u4AkmSuite;
1200
1201     return TRUE;
1202
1203 }  /* rsnPerformPolicySelection */
1204
1205
1206 /*----------------------------------------------------------------------------*/
1207 /*!
1208 * \brief This routine is called to generate WPA IE for beacon frame.
1209 *
1210 * \param[in] pucIeStartAddr Pointer to put the generated WPA IE.
1211 *
1212 * \return The append WPA-None IE length
1213 * \note
1214 *      Called by: JOIN module, compose beacon IE
1215 */
1216 /*----------------------------------------------------------------------------*/
1217 VOID
1218 rsnGenerateWpaNoneIE (
1219     IN  P_ADAPTER_T       prAdapter,
1220     IN  P_MSDU_INFO_T     prMsduInfo
1221     )
1222 {
1223     UINT_32               i;
1224     P_WPA_INFO_ELEM_T     prWpaIE;
1225     UINT_32               u4Suite;
1226     UINT_16               u2SuiteCount;
1227     PUINT_8               cp, cp2;
1228     UINT_8                ucExpendedLen = 0;
1229     PUINT_8               pucBuffer;
1230     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1231
1232     DEBUGFUNC("rsnGenerateWpaNoneIE");
1233
1234     ASSERT(prMsduInfo);
1235
1236     if (prAdapter->rWifiVar.rConnSettings.eAuthMode != AUTH_MODE_WPA_NONE) {
1237         return;
1238     }
1239
1240     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1241
1242     if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1243         return;
1244
1245     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1246                           (UINT_32)prMsduInfo->u2FrameLength);
1247
1248     ASSERT(pucBuffer);
1249
1250     prWpaIE = (P_WPA_INFO_ELEM_T)(pucBuffer);
1251
1252     /* Start to construct a WPA IE. */
1253     /* Fill the Element ID field. */
1254     prWpaIE->ucElemId = ELEM_ID_WPA;
1255
1256     /* Fill the OUI and OUI Type fields. */
1257     prWpaIE->aucOui[0] = 0x00;
1258     prWpaIE->aucOui[1] = 0x50;
1259     prWpaIE->aucOui[2] = 0xF2;
1260     prWpaIE->ucOuiType = VENDOR_OUI_TYPE_WPA;
1261
1262     /* Fill the Version field. */
1263     WLAN_SET_FIELD_16(&prWpaIE->u2Version, 1);    /* version 1 */
1264     ucExpendedLen = 6;
1265
1266     /* Fill the Pairwise Key Cipher Suite List field. */
1267     u2SuiteCount = 0;
1268     cp = (PUINT_8)&prWpaIE->aucPairwiseKeyCipherSuite1[0];
1269
1270     if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_CCMP, &i)) {
1271         u4Suite = WPA_CIPHER_SUITE_CCMP;
1272     }
1273     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_TKIP, &i)) {
1274         u4Suite = WPA_CIPHER_SUITE_TKIP;
1275     }
1276     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP104, &i)) {
1277         u4Suite = WPA_CIPHER_SUITE_WEP104;
1278     }
1279     else if (rsnSearchSupportedCipher(prAdapter, WPA_CIPHER_SUITE_WEP40, &i)) {
1280         u4Suite = WPA_CIPHER_SUITE_WEP40;
1281     }
1282     else {
1283         u4Suite = WPA_CIPHER_SUITE_TKIP;
1284     }
1285
1286     WLAN_SET_FIELD_32(cp, u4Suite);
1287     u2SuiteCount++;
1288     ucExpendedLen += 4;
1289     cp += 4;
1290
1291     /* Fill the Group Key Cipher Suite field as the same in pair-wise key. */
1292     WLAN_SET_FIELD_32(&prWpaIE->u4GroupKeyCipherSuite, u4Suite);
1293     ucExpendedLen += 4;
1294
1295     /* Fill the Pairwise Key Cipher Suite Count field. */
1296     WLAN_SET_FIELD_16(&prWpaIE->u2PairwiseKeyCipherSuiteCount, u2SuiteCount);
1297     ucExpendedLen += 2;
1298
1299     cp2 = cp;
1300
1301     /* Fill the Authentication and Key Management Suite List field. */
1302     u2SuiteCount = 0;
1303     cp += 2;
1304
1305     if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_802_1X, &i)) {
1306         u4Suite = WPA_AKM_SUITE_802_1X;
1307     }
1308     else if (rsnSearchAKMSuite(prAdapter, WPA_AKM_SUITE_PSK, &i)) {
1309         u4Suite = WPA_AKM_SUITE_PSK;
1310     }
1311     else {
1312         u4Suite = WPA_AKM_SUITE_NONE;
1313     }
1314
1315     /* This shall be the only avaiable value for current implementation */
1316     ASSERT(u4Suite == WPA_AKM_SUITE_NONE);
1317
1318     WLAN_SET_FIELD_32(cp, u4Suite);
1319     u2SuiteCount++;
1320     ucExpendedLen += 4;
1321     cp += 4;
1322
1323     /* Fill the Authentication and Key Management Suite Count field. */
1324     WLAN_SET_FIELD_16(cp2, u2SuiteCount);
1325     ucExpendedLen += 2;
1326
1327     /* Fill the Length field. */
1328     prWpaIE->ucLength = (UINT_8)ucExpendedLen;
1329
1330     /* Increment the total IE length for the Element ID and Length fields. */
1331     prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1332
1333 } /* rsnGenerateWpaNoneIE */
1334
1335
1336 /*----------------------------------------------------------------------------*/
1337 /*!
1338 *
1339 * \brief This routine is called to generate WPA IE for
1340 *        associate request frame.
1341 *
1342 * \param[in]  prCurrentBss     The Selected BSS description
1343 *
1344 * \retval The append WPA IE length
1345 *
1346 * \note
1347 *      Called by: AIS module, Associate request
1348 */
1349 /*----------------------------------------------------------------------------*/
1350 VOID
1351 rsnGenerateWPAIE (
1352     IN  P_ADAPTER_T       prAdapter,
1353     IN  P_MSDU_INFO_T     prMsduInfo
1354     )
1355 {
1356     PUCHAR                cp;
1357     PUINT_8               pucBuffer;
1358     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1359
1360     DEBUGFUNC("rsnGenerateWPAIE");
1361
1362     ASSERT(prMsduInfo);
1363     
1364     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
1365         prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
1366
1367     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1368                           (UINT_32)prMsduInfo->u2FrameLength);
1369
1370     ASSERT(pucBuffer);
1371
1372     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1373
1374     //if (eNetworkId != NETWORK_TYPE_AIS_INDEX)
1375     //    return;
1376
1377 #if CFG_ENABLE_WIFI_DIRECT 
1378     if ((1 /* prCurrentBss->fgIEWPA */ && 
1379                 ((prAdapter->fgIsP2PRegistered) && 
1380                 (eNetworkId == NETWORK_TYPE_P2P_INDEX) && 
1381                 (kalP2PGetTkipCipher(prAdapter->prGlueInfo)))) || 
1382                 ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1383         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) 
1384 #else 
1385         if ((1 /* prCurrentBss->fgIEWPA */ && 
1386         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || 
1387         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK)))) 
1388 #endif
1389     {   
1390         if (prP2pSpecificBssInfo->u2WpaIeLen!=0)
1391                 {
1392              kalMemCopy(pucBuffer,prP2pSpecificBssInfo->aucWpaIeBuffer,
1393                          prP2pSpecificBssInfo->u2WpaIeLen);
1394              prMsduInfo->u2FrameLength += prP2pSpecificBssInfo->u2WpaIeLen;
1395                          return;
1396
1397                 }
1398         /* Construct a WPA IE for association request frame. */
1399         WPA_IE(pucBuffer)->ucElemId = ELEM_ID_WPA;
1400         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1401         WPA_IE(pucBuffer)->aucOui[0] = 0x00;
1402         WPA_IE(pucBuffer)->aucOui[1] = 0x50;
1403         WPA_IE(pucBuffer)->aucOui[2] = 0xF2;
1404         WPA_IE(pucBuffer)->ucOuiType = VENDOR_OUI_TYPE_WPA;
1405         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2Version, 1);
1406
1407 #if CFG_ENABLE_WIFI_DIRECT
1408         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1409         {
1410             WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite, WPA_CIPHER_SUITE_TKIP);
1411         }
1412         else
1413 #endif
1414         WLAN_SET_FIELD_32(&WPA_IE(pucBuffer)->u4GroupKeyCipherSuite,
1415             prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedGroupCipher);
1416
1417         cp = (PUCHAR) &WPA_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1418
1419         WLAN_SET_FIELD_16(&WPA_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1420 #if CFG_ENABLE_WIFI_DIRECT
1421         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1422         {
1423             WLAN_SET_FIELD_32(cp, WPA_CIPHER_SUITE_TKIP);
1424         }
1425         else
1426 #endif
1427         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedPairwiseCipher);
1428         cp += 4;
1429
1430         WLAN_SET_FIELD_16(cp, 1);
1431         cp += 2;
1432 #if CFG_ENABLE_WIFI_DIRECT
1433         if (prAdapter->fgIsP2PRegistered && eNetworkId == NETWORK_TYPE_P2P_INDEX)
1434         {
1435             WLAN_SET_FIELD_32(cp, WPA_AKM_SUITE_PSK);
1436         }
1437         else
1438 #endif
1439         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].u4RsnSelectedAKMSuite);
1440         cp += 4;
1441
1442         WPA_IE(pucBuffer)->ucLength = ELEM_ID_WPA_LEN_FIXED;
1443
1444         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1445     }
1446
1447 } /* rsnGenerateWPAIE */
1448
1449
1450 /*----------------------------------------------------------------------------*/
1451 /*!
1452 *
1453 * \brief This routine is called to generate RSN IE for
1454 *        associate request frame.
1455 *
1456 * \param[in]  prMsduInfo     The Selected BSS description
1457 *
1458 * \retval The append RSN IE length
1459 *
1460 * \note
1461 *      Called by: AIS module, P2P module, BOW module Associate request
1462 */
1463 /*----------------------------------------------------------------------------*/
1464 VOID
1465 rsnGenerateRSNIE (
1466     IN  P_ADAPTER_T       prAdapter,
1467     IN  P_MSDU_INFO_T     prMsduInfo
1468     )
1469 {
1470     UINT_32               u4Entry;
1471     PUCHAR                cp;
1472     //UINT_8                ucExpendedLen = 0;
1473     PUINT_8               pucBuffer;
1474     ENUM_NETWORK_TYPE_INDEX_T eNetworkId;
1475     P_STA_RECORD_T  prStaRec;
1476
1477     DEBUGFUNC("rsnGenerateRSNIE");
1478
1479     ASSERT(prMsduInfo);
1480
1481     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
1482                           (UINT_32)prMsduInfo->u2FrameLength);
1483
1484     ASSERT(pucBuffer);
1485
1486     /* Todo:: network id */
1487     eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType;
1488
1489     if (
1490 #if CFG_ENABLE_WIFI_DIRECT
1491         ((prAdapter->fgIsP2PRegistered) &&
1492         (eNetworkId == NETWORK_TYPE_P2P_INDEX) &&
1493         (kalP2PGetCcmpCipher(prAdapter->prGlueInfo))) ||
1494 #endif
1495 #if CFG_ENABLE_BT_OVER_WIFI
1496         (eNetworkId == NETWORK_TYPE_BOW_INDEX) ||
1497 #endif
1498         (eNetworkId == NETWORK_TYPE_AIS_INDEX /* prCurrentBss->fgIERSN */ &&
1499         ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) ||
1500         (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2_PSK))))
1501     {
1502         /* Construct a RSN IE for association request frame. */
1503         RSN_IE(pucBuffer)->ucElemId = ELEM_ID_RSN;
1504         RSN_IE(pucBuffer)->ucLength = ELEM_ID_RSN_LEN_FIXED;
1505         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2Version, 1); // Version
1506         WLAN_SET_FIELD_32(&RSN_IE(pucBuffer)->u4GroupKeyCipherSuite,
1507             prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedGroupCipher); // Group key suite
1508         cp = (PUCHAR) &RSN_IE(pucBuffer)->aucPairwiseKeyCipherSuite1[0];
1509         WLAN_SET_FIELD_16(&RSN_IE(pucBuffer)->u2PairwiseKeyCipherSuiteCount, 1);
1510         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedPairwiseCipher);
1511         cp += 4;
1512         WLAN_SET_FIELD_16(cp, 1); // AKM suite count
1513         cp += 2;
1514         WLAN_SET_FIELD_32(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u4RsnSelectedAKMSuite); // AKM suite
1515         cp += 4;
1516         WLAN_SET_FIELD_16(cp, prAdapter->rWifiVar.arBssInfo[eNetworkId].u2RsnSelectedCapInfo); // Capabilities
1517 #if CFG_SUPPORT_802_11W
1518         if (eNetworkId == NETWORK_TYPE_AIS_INDEX && prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection) {
1519             if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_REQUIRED) {
1520                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC | ELEM_WPA_CAP_MFPR); // Capabilities
1521             }
1522             else if (kalGetMfpSetting(prAdapter->prGlueInfo) == RSN_AUTH_MFP_OPTIONAL) {
1523                 WLAN_SET_FIELD_16(cp, ELEM_WPA_CAP_MFPC); // Capabilities
1524             }
1525         }
1526 #endif
1527         cp += 2;
1528
1529         if (eNetworkId == NETWORK_TYPE_AIS_INDEX)
1530             prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
1531
1532         if (eNetworkId == NETWORK_TYPE_AIS_INDEX &&
1533             rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) {
1534             //DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n"));
1535             //DBGLOG(RSN, TRACE, ("addr " MACSTR" PMKID "MACSTR"\n",
1536             //    MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID), MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1537             if (prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].fgPmkidExist) {
1538                 RSN_IE(pucBuffer)->ucLength = 38;
1539                 WLAN_SET_FIELD_16(cp, 1); // PMKID count
1540                 cp += 2;
1541                 DBGLOG(RSN, TRACE, ("BSSID "MACSTR" ind=%d\n", MAC2STR(prStaRec->aucMacAddr), u4Entry));
1542                 DBGLOG(RSN, TRACE, ("use PMKID "MACSTR"\n", MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID)));
1543                 kalMemCopy(cp, (PVOID)prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arPMKID,
1544                     sizeof(PARAM_PMKID_VALUE));
1545                 //ucExpendedLen = 40;
1546             }
1547             else {
1548                 WLAN_SET_FIELD_16(cp, 0); // PMKID count
1549                 //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1550 #if CFG_SUPPORT_802_11W
1551                 cp += 2;
1552                 RSN_IE(pucBuffer)->ucLength += 2;
1553 #endif
1554             }
1555         }
1556         else {
1557             WLAN_SET_FIELD_16(cp, 0); // PMKID count
1558             //ucExpendedLen = ELEM_ID_RSN_LEN_FIXED + 2;
1559 #if CFG_SUPPORT_802_11W
1560             cp += 2;
1561             RSN_IE(pucBuffer)->ucLength += 2;
1562 #endif
1563         }
1564
1565 #if CFG_SUPPORT_802_11W
1566         if ((eNetworkId == NETWORK_TYPE_AIS_INDEX) && (kalGetMfpSetting(prAdapter->prGlueInfo) != RSN_AUTH_MFP_DISABLED) /* (mgmt_group_cipher == WPA_CIPHER_AES_128_CMAC) */ ) {
1567             WLAN_SET_FIELD_32(cp, RSN_CIPHER_SUITE_AES_128_CMAC);
1568             cp += 4;
1569             RSN_IE(pucBuffer)->ucLength += 4;
1570         }
1571 #endif
1572         prMsduInfo->u2FrameLength += IE_SIZE(pucBuffer);
1573     }
1574
1575 } /* rsnGenerateRSNIE */
1576
1577 /*----------------------------------------------------------------------------*/
1578 /*!
1579 * \brief Parse the given IE buffer and check if it is WFA IE and return Type and
1580 *        SubType for further process.
1581 *
1582 * \param[in] pucBuf             Pointer to the buffer of WFA Information Element.
1583 * \param[out] pucOuiType        Pointer to the storage of OUI Type.
1584 * \param[out] pu2SubTypeVersion Pointer to the storage of OUI SubType and Version.
1585
1586 * \retval TRUE  Parse IE ok
1587 * \retval FALSE Parse IE fail
1588 */
1589 /*----------------------------------------------------------------------------*/
1590 BOOLEAN
1591 rsnParseCheckForWFAInfoElem (
1592     IN  P_ADAPTER_T       prAdapter,
1593     IN  PUINT_8           pucBuf,
1594     OUT PUINT_8           pucOuiType,
1595     OUT PUINT_16          pu2SubTypeVersion
1596     )
1597 {
1598     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
1599     P_IE_WFA_T prWfaIE;
1600
1601     ASSERT(pucBuf);
1602     ASSERT(pucOuiType);
1603     ASSERT(pu2SubTypeVersion);
1604     prWfaIE = (P_IE_WFA_T)pucBuf;
1605
1606     do {
1607         if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
1608             break;
1609         }
1610         else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
1611                  prWfaIE->aucOui[1] != aucWfaOui[1] ||
1612                  prWfaIE->aucOui[2] != aucWfaOui[2]) {
1613             break;
1614         }
1615
1616         *pucOuiType = prWfaIE->ucOuiType;
1617         WLAN_GET_FIELD_16(&prWfaIE->aucOuiSubTypeVersion[0], pu2SubTypeVersion);
1618
1619         return TRUE;
1620     }
1621     while (FALSE);
1622
1623     return FALSE;
1624
1625 } /* end of rsnParseCheckForWFAInfoElem() */
1626
1627 #if CFG_SUPPORT_AAA
1628 /*----------------------------------------------------------------------------*/
1629 /*!
1630 * \brief Parse the given IE buffer and check if it is RSN IE with CCMP PSK
1631 *
1632 * \param[in] prAdapter             Pointer to Adapter
1633 * \param[in] prSwRfb               Pointer to the rx buffer
1634 * \param[in] pIE                      Pointer rthe buffer of Information Element.
1635 * \param[out] prStatusCode     Pointer to the return status code.
1636
1637 * \retval none
1638 */
1639 /*----------------------------------------------------------------------------*/
1640 void
1641 rsnParserCheckForRSNCCMPPSK(
1642     P_ADAPTER_T           prAdapter,
1643     P_RSN_INFO_ELEM_T     prIe,
1644     PUINT_16              pu2StatusCode
1645     )
1646 {
1647
1648     RSN_INFO_T            rRsnIe;
1649
1650     ASSERT(prAdapter);
1651     ASSERT(prIe);
1652     ASSERT(pu2StatusCode);
1653
1654     *pu2StatusCode = STATUS_CODE_INVALID_INFO_ELEMENT;
1655
1656     if (rsnParseRsnIE(prAdapter, prIe, &rRsnIe)) {
1657         if ((rRsnIe.u4PairwiseKeyCipherSuiteCount != 1) || (rRsnIe.au4PairwiseKeyCipherSuite[0] != RSN_CIPHER_SUITE_CCMP)) {
1658             *pu2StatusCode = STATUS_CODE_INVALID_PAIRWISE_CIPHER;
1659             return;
1660         }
1661         if ((rRsnIe.u4GroupKeyCipherSuite != RSN_CIPHER_SUITE_CCMP)) {
1662             *pu2StatusCode = STATUS_CODE_INVALID_GROUP_CIPHER;
1663             return;
1664         }
1665         if ((rRsnIe.u4AuthKeyMgtSuiteCount != 1) || (rRsnIe.au4AuthKeyMgtSuite[0] != RSN_AKM_SUITE_PSK)) {
1666             *pu2StatusCode = STATUS_CODE_INVALID_AKMP;
1667             return;
1668         }
1669
1670         DBGLOG(RSN, TRACE, ("RSN with CCMP-PSK\n" ));
1671             *pu2StatusCode = WLAN_STATUS_SUCCESS;
1672     }
1673
1674 }
1675 #endif
1676
1677 /*----------------------------------------------------------------------------*/
1678 /*!
1679 * \brief This routine is called to generate an authentication event to NDIS.
1680 *
1681 * \param[in] u4Flags Authentication event: \n
1682 *                     PARAM_AUTH_REQUEST_REAUTH 0x01 \n
1683 *                     PARAM_AUTH_REQUEST_KEYUPDATE 0x02 \n
1684 *                     PARAM_AUTH_REQUEST_PAIRWISE_ERROR 0x06 \n
1685 *                     PARAM_AUTH_REQUEST_GROUP_ERROR 0x0E \n
1686 *
1687 * \return (none)
1688 */
1689 /*----------------------------------------------------------------------------*/
1690 VOID
1691 rsnGenMicErrorEvent (
1692     IN  P_ADAPTER_T       prAdapter,
1693     IN  BOOLEAN           fgFlags
1694     )
1695 {
1696     P_PARAM_AUTH_EVENT_T prAuthEvent;
1697
1698     DEBUGFUNC("rsnGenMicErrorEvent");
1699
1700     prAuthEvent = (P_PARAM_AUTH_EVENT_T)prAdapter->aucIndicationEventBuffer;
1701
1702     /* Status type: Authentication Event */
1703     prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
1704
1705     /* Authentication request */
1706     prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
1707     kalMemCopy((PVOID)prAuthEvent->arRequest[0].arBssid, (PVOID)prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].aucBSSID, MAC_ADDR_LEN);
1708
1709     if (fgFlags == TRUE)
1710         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
1711     else
1712         prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
1713
1714     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1715         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1716         (PVOID)prAuthEvent,
1717         sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
1718
1719 } /* rsnGenMicErrorEvent */
1720
1721
1722 /*----------------------------------------------------------------------------*/
1723 /*!
1724 * \brief This routine is called to handle TKIP MIC failures.
1725 *
1726 * \param[in] adapter_p Pointer to the adapter object data area.
1727 * \param[in] prSta Pointer to the STA which occur MIC Error
1728 * \param[in] fgErrorKeyType type of error key
1729 *
1730 * \retval none
1731 */
1732 /*----------------------------------------------------------------------------*/
1733 VOID
1734 rsnTkipHandleMICFailure (
1735     IN  P_ADAPTER_T       prAdapter,
1736     IN  P_STA_RECORD_T    prSta,
1737     IN  BOOLEAN           fgErrorKeyType
1738     )
1739 {
1740     //UINT_32               u4RsnaCurrentMICFailTime;
1741     //P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1742
1743     DEBUGFUNC("rsnTkipHandleMICFailure");
1744
1745     ASSERT(prAdapter);
1746 #if 1
1747     rsnGenMicErrorEvent(prAdapter,/* prSta,*/ fgErrorKeyType);
1748
1749     /* Generate authentication request event. */
1750     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1751         fgErrorKeyType));
1752 #else
1753     ASSERT(prSta);
1754
1755     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1756
1757     /* Record the MIC error occur time. */
1758     GET_CURRENT_SYSTIME(&u4RsnaCurrentMICFailTime);
1759
1760     /* Generate authentication request event. */
1761     DBGLOG(RSN, INFO, ("Generate TKIP MIC error event (type: 0%d)\n",
1762         fgErrorKeyType));
1763
1764     /* If less than 60 seconds have passed since a previous TKIP MIC failure,
1765        disassociate from the AP and wait for 60 seconds before (re)associating
1766        with the same AP. */
1767     if (prAisSpecBssInfo->u4RsnaLastMICFailTime != 0 &&
1768         !CHECK_FOR_TIMEOUT(u4RsnaCurrentMICFailTime,
1769             prAisSpecBssInfo->u4RsnaLastMICFailTime,
1770             SEC_TO_SYSTIME(TKIP_COUNTERMEASURE_SEC))) {
1771         /* If less than 60 seconds expired since last MIC error, we have to
1772            block traffic. */
1773
1774         DBGLOG(RSN, INFO, ("Start blocking traffic!\n"));
1775         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1776
1777         secFsmEventStartCounterMeasure(prAdapter, prSta);
1778     }
1779     else {
1780         rsnGenMicErrorEvent( prAdapter,/* prSta,*/ fgErrorKeyType);
1781         DBGLOG(RSN, INFO, ("First TKIP MIC error!\n"));
1782     }
1783
1784     COPY_SYSTIME(prAisSpecBssInfo->u4RsnaLastMICFailTime, u4RsnaCurrentMICFailTime);
1785 #endif
1786 }   /* rsnTkipHandleMICFailure */
1787
1788
1789 /*----------------------------------------------------------------------------*/
1790 /*!
1791 * \brief This function is called to select a list of BSSID from
1792 *        the scan results for PMKID candidate list.
1793 *
1794 * \param[in] prBssDesc the BSS Desc at scan result list
1795 * \param[out] pu4CandidateCount Pointer to the number of selected candidates.
1796 *                         It is set to zero if no BSSID matches our requirement.
1797 *
1798 * \retval none
1799 */
1800 /*----------------------------------------------------------------------------*/
1801 VOID
1802 rsnSelectPmkidCandidateList (
1803     IN  P_ADAPTER_T       prAdapter,
1804     IN P_BSS_DESC_T       prBssDesc
1805     )
1806 {
1807     P_CONNECTION_SETTINGS_T prConnSettings;
1808     P_AIS_BSS_INFO_T      prAisBssInfo;
1809
1810     DEBUGFUNC("rsnSelectPmkidCandidateList");
1811
1812     ASSERT(prBssDesc);
1813
1814     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1815     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
1816
1817     /* Search a BSS with the same SSID from the given BSS description set. */
1818     //DBGLOG(RSN, TRACE, ("Check scan result ["MACSTR"]\n",
1819     //    MAC2STR(prBssDesc->aucBSSID)));
1820
1821     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1822                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1823         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1824         return;
1825     }
1826
1827 #if 0
1828     if ((prBssDesc->u2BSSBasicRateSet &
1829          ~(rPhyAttributes[prAisBssInfo->ePhyType].u2SupportedRateSet)) ||
1830         prBssDesc->fgIsUnknownBssBasicRate) {
1831         DBGLOG(RSN, TRACE, ("-- Rate set not matched\n"));
1832         return;
1833     }
1834
1835     if (/* prBssDesc->u4RsnSelectedPairwiseCipher != prAisBssInfo->u4RsnSelectedPairwiseCipher ||*/
1836         prBssDesc->u4RsnSelectedGroupCipher != prAisBssInfo->u4RsnSelectedGroupCipher /*||
1837         prBssDesc->u4RsnSelectedAKMSuite != prAisBssInfo->u4RsnSelectedAKMSuite */) {
1838         DBGLOG(RSN, TRACE, ("-- Encrypt status not matched for PMKID \n"));
1839         return;
1840     }
1841 #endif
1842
1843     rsnUpdatePmkidCandidateList(prAdapter, prBssDesc);
1844
1845 }   /* rsnSelectPmkidCandidateList */
1846
1847
1848 /*----------------------------------------------------------------------------*/
1849 /*!
1850 * \brief This function is called to select a list of BSSID from
1851 *        the scan results for PMKID candidate list.
1852 *
1853 * \param[in] prBssDesc the BSS DESC at scan result list
1854 *
1855 * \retval none
1856 */
1857 /*----------------------------------------------------------------------------*/
1858 VOID
1859 rsnUpdatePmkidCandidateList (
1860     IN  P_ADAPTER_T       prAdapter,
1861     IN  P_BSS_DESC_T      prBssDesc
1862     )
1863 {
1864     UINT_32                   i;
1865     P_CONNECTION_SETTINGS_T   prConnSettings;
1866     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1867
1868     DEBUGFUNC("rsnUpdatePmkidCandidateList");
1869
1870     ASSERT(prBssDesc);
1871
1872     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
1873     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1874
1875     if (UNEQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen,
1876                    prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
1877         DBGLOG(RSN, TRACE, ("-- SSID not matched\n"));
1878         return;
1879     }
1880
1881     for (i = 0; i < CFG_MAX_PMKID_CACHE; i++) {
1882         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))
1883             return;
1884     }
1885
1886     /* If the number of selected BSSID exceed MAX_NUM_PMKID_CACHE(16),
1887        then we only store MAX_NUM_PMKID_CACHE(16) in PMKID cache */
1888     if ((prAisSpecBssInfo->u4PmkidCandicateCount + 1)  > CFG_MAX_PMKID_CACHE) {
1889         prAisSpecBssInfo->u4PmkidCandicateCount --;
1890     }
1891
1892     i = prAisSpecBssInfo->u4PmkidCandicateCount;
1893
1894     COPY_MAC_ADDR((PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1895         (PVOID)prBssDesc->aucBSSID);
1896
1897     if (prBssDesc->u2RsnCap & MASK_RSNIE_CAP_PREAUTH) {
1898         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 1;
1899         DBGLOG(RSN, TRACE, ("Add " MACSTR " with pre-auth to candidate list\n",
1900             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1901     }
1902     else {
1903         prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0;
1904         DBGLOG(RSN, TRACE, ("Add " MACSTR " without pre-auth to candidate list\n",
1905             MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
1906     }
1907
1908     prAisSpecBssInfo->u4PmkidCandicateCount ++;
1909
1910 }   /* rsnUpdatePmkidCandidateList */
1911
1912
1913 /*----------------------------------------------------------------------------*/
1914 /*!
1915 * \brief This routine is called to search the desired entry in
1916 *        PMKID cache according to the BSSID
1917 *
1918 * \param[in] pucBssid Pointer to the BSSID
1919 * \param[out] pu4EntryIndex Pointer to place the found entry index
1920 *
1921 * \retval TRUE, if found one entry for specified BSSID
1922 * \retval FALSE, if not found
1923 */
1924 /*----------------------------------------------------------------------------*/
1925 BOOLEAN
1926 rsnSearchPmkidEntry (
1927     IN  P_ADAPTER_T       prAdapter,
1928     IN  PUINT_8           pucBssid,
1929     OUT PUINT_32          pu4EntryIndex
1930     )
1931 {
1932     UINT_32 i;
1933     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
1934
1935     DEBUGFUNC("rsnSearchPmkidEntry");
1936
1937     ASSERT(pucBssid);
1938     ASSERT(pu4EntryIndex);
1939
1940     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1941
1942     if (prAisSpecBssInfo->u4PmkidCacheCount > CFG_MAX_PMKID_CACHE) {
1943         return FALSE;
1944     }
1945
1946     ASSERT(prAisSpecBssInfo->u4PmkidCacheCount <= CFG_MAX_PMKID_CACHE);
1947
1948     /* Search for desired BSSID */
1949     for (i = 0; i < prAisSpecBssInfo->u4PmkidCacheCount; i++) {
1950         if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[i].rBssidInfo.arBSSID, pucBssid,
1951             MAC_ADDR_LEN)) {
1952             break;
1953         }
1954     }
1955
1956     /* If desired BSSID is found, then set the PMKID */
1957     if (i < prAisSpecBssInfo->u4PmkidCacheCount) {
1958         *pu4EntryIndex = i;
1959
1960         return TRUE;
1961     }
1962
1963     return FALSE;
1964 }   /* rsnSearchPmkidEntry */
1965
1966
1967 /*----------------------------------------------------------------------------*/
1968 /*!
1969 * \brief This routine is called to check if there is difference
1970 *        between PMKID candicate list and PMKID cache. If there
1971 *        is new candicate that no cache entry is available, then
1972 *        add a new entry for the new candicate in the PMKID cache
1973 *        and set the PMKID indication flag to TRUE.
1974 *
1975 * \retval TRUE, if new member in the PMKID candicate list
1976 * \retval FALSe, if no new member in the PMKID candicate list
1977 */
1978 /*----------------------------------------------------------------------------*/
1979 BOOLEAN
1980 rsnCheckPmkidCandicate (
1981     IN  P_ADAPTER_T       prAdapter
1982    )
1983 {
1984     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
1985     UINT_32                    i; // Index for PMKID candicate
1986     UINT_32                    j; // Indix for PMKID cache
1987     BOOLEAN                    status = FALSE;
1988
1989     DEBUGFUNC("rsnCheckPmkidCandicate");
1990
1991     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
1992
1993     /* Check for each candicate */
1994     for (i = 0; i < prAisSpecBssInfo->u4PmkidCandicateCount; i++) {
1995         for (j = 0; j < prAisSpecBssInfo->u4PmkidCacheCount; j++) {
1996             if (!kalMemCmp(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
1997                     prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
1998                     MAC_ADDR_LEN)) {
1999                 //DBGLOG(RSN, TRACE, (MACSTR" at PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
2000                 break;
2001             }
2002         }
2003
2004         /* No entry found in PMKID cache for the candicate, add new one */
2005         if (j == prAisSpecBssInfo->u4PmkidCacheCount && prAisSpecBssInfo->u4PmkidCacheCount < CFG_MAX_PMKID_CACHE) {
2006             DBGLOG(RSN, TRACE, ("Add "MACSTR" to PMKID cache!!\n", MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid)));
2007             kalMemCopy((PVOID)prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.arBSSID,
2008                 (PVOID)prAisSpecBssInfo->arPmkidCandicate[i].aucBssid,
2009                 MAC_ADDR_LEN);
2010             prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].fgPmkidExist = FALSE;
2011             prAisSpecBssInfo->u4PmkidCacheCount++;
2012
2013             status = TRUE;
2014         }
2015     }
2016
2017     return status;
2018 } /* rsnCheckPmkidCandicate */
2019
2020
2021 /*----------------------------------------------------------------------------*/
2022 /*!
2023 * \brief This function is called to wait a duration to indicate the pre-auth AP candicate
2024 *
2025 * \return (none)
2026 */
2027 /*----------------------------------------------------------------------------*/
2028 VOID
2029 rsnIndicatePmkidCand (
2030     IN  P_ADAPTER_T       prAdapter,
2031     IN  UINT_32           u4Parm
2032     )
2033 {
2034     DBGLOG(RSN, EVENT, ("Security - Time to indicate the PMKID cand.\n"));
2035
2036     /* If the authentication mode is WPA2 and indication PMKID flag
2037        is available, then we indicate the PMKID candidate list to NDIS and
2038        clear the flag, indicatePMKID */
2039
2040     if (prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX].eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2041         prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2042         rsnGeneratePmkidIndication(prAdapter);
2043     }
2044
2045     return;
2046 } /* end of rsnIndicatePmkidCand() */
2047
2048
2049 /*----------------------------------------------------------------------------*/
2050 /*!
2051 * \brief This routine is called to check the BSS Desc at scan result
2052 *             with pre-auth cap at wpa2 mode. If there
2053 *             is candicate that no cache entry is available, then
2054 *             add a new entry for the new candicate in the PMKID cache
2055 *             and set the PMKID indication flag to TRUE.
2056 *
2057 * \param[in] prBss The BSS Desc at scan result
2058 *
2059 * \return none
2060 */
2061 /*----------------------------------------------------------------------------*/
2062 VOID
2063 rsnCheckPmkidCache (
2064     IN  P_ADAPTER_T       prAdapter,
2065     IN  P_BSS_DESC_T      prBss
2066     )
2067 {
2068     P_AIS_BSS_INFO_T           prAisBssInfo;
2069     P_AIS_SPECIFIC_BSS_INFO_T  prAisSpecBssInfo;
2070     P_CONNECTION_SETTINGS_T    prConnSettings;
2071
2072     DEBUGFUNC("rsnCheckPmkidCandicate");
2073
2074     ASSERT(prBss);
2075
2076     prConnSettings = &prAdapter->rWifiVar.rConnSettings;
2077     prAisBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2078     prAisSpecBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2079
2080     if ((prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) &&
2081        (prConnSettings->eAuthMode == AUTH_MODE_WPA2)) {
2082         rsnSelectPmkidCandidateList(prAdapter, prBss);
2083
2084         /* Set indication flag of PMKID to TRUE, and then connHandleNetworkConnection()
2085            will indicate this later */
2086         if (rsnCheckPmkidCandicate(prAdapter)) {
2087             DBGLOG(RSN, TRACE, ("Prepare a timer to indicate candidate PMKID Candidate\n"));
2088             cnmTimerStopTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer);
2089             cnmTimerStartTimer(prAdapter, &prAisSpecBssInfo->rPreauthenticationTimer,
2090                     SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2091         }
2092     }
2093 }
2094
2095
2096 /*----------------------------------------------------------------------------*/
2097 /*!
2098 * \brief This routine is called to generate an PMKID candidate list
2099 *        indication to NDIS.
2100 *
2101 * \param[in] prAdapter Pointer to the adapter object data area.
2102 * \param[in] u4Flags PMKID candidate list event:
2103 *                    PARAM_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
2104 *
2105 * \retval none
2106 */
2107 /*----------------------------------------------------------------------------*/
2108 VOID
2109 rsnGeneratePmkidIndication (
2110     IN  P_ADAPTER_T       prAdapter
2111     )
2112 {
2113     P_PARAM_STATUS_INDICATION_T    prStatusEvent;
2114     P_PARAM_PMKID_CANDIDATE_LIST_T prPmkidEvent;
2115     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecificBssInfo;
2116     UINT_8                i, j = 0, count = 0;
2117     UINT_32               u4LenOfUsedBuffer;
2118
2119     DEBUGFUNC("rsnGeneratePmkidIndication");
2120
2121     ASSERT(prAdapter);
2122
2123     prStatusEvent =
2124         (P_PARAM_STATUS_INDICATION_T)prAdapter->aucIndicationEventBuffer;
2125
2126     /* Status type: PMKID Candidatelist Event */
2127     prStatusEvent->eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
2128     ASSERT(prStatusEvent);
2129
2130     prPmkidEvent = (P_PARAM_PMKID_CANDIDATE_LIST_T)(&prStatusEvent->eStatusType + 1);
2131     ASSERT(prPmkidEvent);
2132
2133     prAisSpecificBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2134     ASSERT(prAisSpecificBssInfo);
2135
2136     for (i = 0; i < prAisSpecificBssInfo->u4PmkidCandicateCount; i++) {
2137         for (j = 0; j < prAisSpecificBssInfo->u4PmkidCacheCount; j++) {
2138             if (EQUAL_MAC_ADDR( prAisSpecificBssInfo->arPmkidCache[j].rBssidInfo.arBSSID,
2139                 prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid) &&
2140                 (prAisSpecificBssInfo->arPmkidCache[j].fgPmkidExist == TRUE)){
2141                 break;
2142             }
2143         }
2144         if (count >= CFG_MAX_PMKID_CACHE) {
2145             break;
2146         }
2147
2148         if (j == prAisSpecificBssInfo->u4PmkidCacheCount) {
2149             kalMemCopy((PVOID)prPmkidEvent->arCandidateList[count].arBSSID,
2150                 (PVOID)prAisSpecificBssInfo->arPmkidCandicate[i].aucBssid,
2151                 PARAM_MAC_ADDR_LEN);
2152             prPmkidEvent->arCandidateList[count].u4Flags =
2153                 prAisSpecificBssInfo->arPmkidCandicate[i].u4PreAuthFlags;
2154             DBGLOG(RSN, TRACE, (MACSTR" %d\n", MAC2STR(prPmkidEvent->arCandidateList[count].arBSSID),
2155                 prPmkidEvent->arCandidateList[count].u4Flags));
2156             count++;
2157         }
2158     }
2159
2160     /* PMKID Candidate List */
2161     prPmkidEvent->u4Version = 1;
2162     prPmkidEvent->u4NumCandidates = count;
2163     DBGLOG(RSN, TRACE, ("rsnGeneratePmkidIndication #%d\n", prPmkidEvent->u4NumCandidates));
2164     u4LenOfUsedBuffer = sizeof(ENUM_STATUS_TYPE_T) + (2 * sizeof(UINT_32)) +
2165         (count * sizeof(PARAM_PMKID_CANDIDATE_T));
2166     //dumpMemory8((PUINT_8)prAdapter->aucIndicationEventBuffer, u4LenOfUsedBuffer);
2167
2168     kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2169         WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
2170         (PVOID) prAdapter->aucIndicationEventBuffer,
2171         u4LenOfUsedBuffer);
2172
2173 }   /* rsnGeneratePmkidIndication */
2174 #endif
2175
2176 #if CFG_SUPPORT_WPS2
2177 /*----------------------------------------------------------------------------*/
2178 /*!
2179 *
2180 * \brief This routine is called to generate WSC IE for
2181 *        associate request frame.
2182 *
2183 * \param[in]  prCurrentBss     The Selected BSS description
2184 *
2185 * \retval The append WSC IE length
2186 *
2187 * \note
2188 *      Called by: AIS module, Associate request
2189 */
2190 /*----------------------------------------------------------------------------*/
2191 VOID
2192 rsnGenerateWSCIE (
2193     IN P_ADAPTER_T          prAdapter,
2194     IN P_MSDU_INFO_T        prMsduInfo
2195     )
2196 {
2197     PUINT_8                 pucBuffer;
2198
2199     ASSERT(prAdapter);
2200     ASSERT(prMsduInfo);
2201
2202     if (prMsduInfo->ucNetworkType != NETWORK_TYPE_AIS_INDEX)
2203         return;
2204
2205     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
2206                           (UINT_32)prMsduInfo->u2FrameLength);
2207
2208     /* ASSOC INFO IE ID: 221 :0xDD */
2209     if (prAdapter->prGlueInfo->u2WSCAssocInfoIELen) {
2210         kalMemCopy(pucBuffer, &prAdapter->prGlueInfo->aucWSCAssocInfoIE, prAdapter->prGlueInfo->u2WSCAssocInfoIELen);
2211         prMsduInfo->u2FrameLength += prAdapter->prGlueInfo->u2WSCAssocInfoIELen;
2212     }
2213
2214 }
2215 #endif
2216
2217
2218 #if CFG_SUPPORT_802_11W
2219
2220 /*----------------------------------------------------------------------------*/
2221 /*!
2222 * \brief to check if the Bip Key installed or not
2223 *
2224 * \param[in]
2225 *           prAdapter
2226 *
2227 * \return
2228 *           TRUE
2229 *           FALSE
2230 */
2231 /*----------------------------------------------------------------------------*/
2232 UINT_32
2233 rsnCheckBipKeyInstalled (
2234     IN P_ADAPTER_T                  prAdapter,
2235     IN P_STA_RECORD_T               prStaRec
2236     )
2237 {
2238     if (prStaRec && prStaRec->ucNetTypeIndex == (UINT_8)NETWORK_TYPE_AIS_INDEX)
2239         return prAdapter->rWifiVar.rAisSpecificBssInfo.fgBipKeyInstalled;
2240     else
2241         return FALSE;
2242 }
2243
2244 /*----------------------------------------------------------------------------*/
2245 /*!
2246 *
2247 * \brief This routine is called to check the Sa query timeout.
2248 *
2249 *
2250 * \note
2251 *      Called by: AIS module, Handle by Sa Quert timeout
2252 */
2253 /*----------------------------------------------------------------------------*/
2254 UINT_8
2255 rsnCheckSaQueryTimeout (
2256     IN P_ADAPTER_T                  prAdapter
2257     )
2258 {
2259     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2260     UINT_32 now;
2261
2262     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2263     ASSERT(prBssSpecInfo);
2264
2265     GET_CURRENT_SYSTIME(&now);
2266
2267     if (CHECK_FOR_TIMEOUT(now,
2268                 prBssSpecInfo->u4SaQueryStart,
2269                 TU_TO_MSEC(1000))) {
2270         LOG_FUNC("association SA Query timed out\n");
2271
2272         prBssSpecInfo->ucSaQueryTimedOut = 1;
2273         kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2274         prBssSpecInfo->pucSaQueryTransId = NULL;
2275         prBssSpecInfo->u4SaQueryCount = 0;
2276         cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2277         /* Re-connect */
2278         kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2279                 WLAN_STATUS_MEDIA_DISCONNECT,
2280                 NULL,
2281                 0);
2282
2283         return 1;
2284     }
2285
2286     return 0;
2287 }
2288
2289 /*----------------------------------------------------------------------------*/
2290 /*!
2291 *
2292 * \brief This routine is called to start the 802.11w sa query timer.
2293 *
2294 *
2295 * \note
2296 *      Called by: AIS module, Handle Rx mgmt request
2297 */
2298 /*----------------------------------------------------------------------------*/
2299 void rsnStartSaQueryTimer (
2300     IN P_ADAPTER_T                  prAdapter
2301     )
2302 {
2303     P_BSS_INFO_T                    prBssInfo;
2304     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2305     P_MSDU_INFO_T                   prMsduInfo;
2306     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2307     UINT_16                         u2PayloadLen;
2308     PUINT_8                         pucTmp = NULL;
2309     UINT_8                          ucTransId[ACTION_SA_QUERY_TR_ID_LEN];
2310
2311     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2312     ASSERT(prBssInfo);
2313
2314     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2315     ASSERT(prBssSpecInfo);
2316
2317     LOG_FUNC("MFP: Start Sa Query\n");
2318
2319     if (prBssSpecInfo->u4SaQueryCount > 0 &&
2320         rsnCheckSaQueryTimeout(prAdapter)) {
2321         LOG_FUNC("MFP: u4SaQueryCount count =%d\n", prBssSpecInfo->u4SaQueryCount);
2322         return;
2323     }
2324
2325     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2326                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2327
2328     if (!prMsduInfo)
2329         return;
2330
2331     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2332         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2333
2334     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2335     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2336
2337     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2338     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2339     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2340
2341     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2342     prTxFrame->ucAction = ACTION_SA_QUERY_REQUEST;
2343
2344     if (prBssSpecInfo->u4SaQueryCount == 0) {
2345         GET_CURRENT_SYSTIME(&prBssSpecInfo->u4SaQueryStart);
2346     }
2347
2348     if (prBssSpecInfo->u4SaQueryCount) {
2349         pucTmp = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2350         if (!pucTmp) {
2351             DBGLOG(RSN, INFO, ("MFP: Fail to alloc tmp buffer for backup sa query id\n"));
2352             return;
2353         }
2354         kalMemCopy(pucTmp, prBssSpecInfo->pucSaQueryTransId, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2355     }
2356
2357     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2358
2359     ucTransId[0] = (UINT_8)(kalRandomNumber() & 0xFF);
2360     ucTransId[1] = (UINT_8)(kalRandomNumber() & 0xFF);
2361
2362     kalMemCopy(prTxFrame->ucTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2363
2364     prBssSpecInfo->u4SaQueryCount++;
2365
2366     prBssSpecInfo->pucSaQueryTransId = kalMemAlloc(prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN, VIR_MEM_TYPE);
2367     if (!prBssSpecInfo->pucSaQueryTransId) {
2368         DBGLOG(RSN, INFO, ("MFP: Fail to alloc buffer for sa query id list\n"));
2369         return;
2370     }
2371
2372     if (pucTmp) {
2373         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, pucTmp, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2374         kalMemCopy(&prBssSpecInfo->pucSaQueryTransId[(prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN],
2375             ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2376         kalMemFree(pucTmp, VIR_MEM_TYPE, (prBssSpecInfo->u4SaQueryCount - 1) * ACTION_SA_QUERY_TR_ID_LEN);
2377     }
2378     else {
2379         kalMemCopy(prBssSpecInfo->pucSaQueryTransId, ucTransId, ACTION_SA_QUERY_TR_ID_LEN);
2380     }
2381
2382     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2383
2384     //4 Update information of MSDU_INFO_T
2385     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2386     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2387     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2388     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2389     prMsduInfo->fgIs802_1x = FALSE;
2390     prMsduInfo->fgIs802_11 = TRUE;
2391     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2392     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2393     prMsduInfo->pfTxDoneHandler = NULL;
2394     prMsduInfo->fgIsBasicRate = FALSE;
2395
2396     //4 Enqueue the frame to send this action frame.
2397     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2398
2399     DBGLOG(RSN, TRACE, ("Set SA Query timer %d (%d sec)\n", prBssSpecInfo->u4SaQueryCount, prBssInfo->u2ObssScanInterval));
2400
2401     cnmTimerStartTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer,
2402         TU_TO_MSEC(201));
2403
2404 }
2405
2406
2407 /*----------------------------------------------------------------------------*/
2408 /*!
2409 *
2410 * \brief This routine is called to start the 802.11w sa query.
2411 *
2412 *
2413 * \note
2414 *      Called by: AIS module, Handle Rx mgmt request
2415 */
2416 /*----------------------------------------------------------------------------*/
2417 void rsnStartSaQuery (
2418     IN P_ADAPTER_T                  prAdapter
2419     )
2420 {
2421     rsnStartSaQueryTimer(prAdapter);
2422 }
2423
2424
2425 /*----------------------------------------------------------------------------*/
2426 /*!
2427 *
2428 * \brief This routine is called to stop the 802.11w sa query.
2429 *
2430 *
2431 * \note
2432 *      Called by: AIS module, Handle Rx mgmt request
2433 */
2434 /*----------------------------------------------------------------------------*/
2435 void rsnStopSaQuery (
2436     IN P_ADAPTER_T                  prAdapter
2437     )
2438 {
2439     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2440
2441     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2442     ASSERT(prBssSpecInfo);
2443
2444     cnmTimerStopTimer(prAdapter, &prBssSpecInfo->rSaQueryTimer);
2445     kalMemFree(prBssSpecInfo->pucSaQueryTransId, VIR_MEM_TYPE, prBssSpecInfo->u4SaQueryCount * ACTION_SA_QUERY_TR_ID_LEN);
2446     prBssSpecInfo->pucSaQueryTransId = NULL;
2447     prBssSpecInfo->u4SaQueryCount = 0;
2448 }
2449
2450 /*----------------------------------------------------------------------------*/
2451 /*!
2452 *
2453 * \brief This routine is called to process the 802.11w sa query action frame.
2454 *
2455 *
2456 * \note
2457 *      Called by: AIS module, Handle Rx mgmt request
2458 */
2459 /*----------------------------------------------------------------------------*/
2460 void
2461 rsnSaQueryRequest (
2462     IN P_ADAPTER_T                  prAdapter,
2463     IN P_SW_RFB_T                   prSwRfb
2464     )
2465 {
2466     P_BSS_INFO_T                    prBssInfo;
2467     P_MSDU_INFO_T                   prMsduInfo;
2468     P_ACTION_SA_QUERY_FRAME         prRxFrame = NULL;
2469     UINT_16                         u2PayloadLen;
2470     P_STA_RECORD_T                  prStaRec;
2471     P_ACTION_SA_QUERY_FRAME         prTxFrame;
2472
2473     prBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX];
2474     ASSERT(prBssInfo);
2475
2476     prRxFrame = (P_ACTION_SA_QUERY_FRAME)prSwRfb->pvHeader;
2477     if (!prRxFrame)
2478         return;
2479
2480     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2481
2482     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Request from "
2483            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2484
2485     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2486             ACTION_SA_QUERY_TR_ID_LEN);
2487
2488     if (kalGetMediaStateIndicated(prAdapter->prGlueInfo) == PARAM_MEDIA_STATE_DISCONNECTED) {
2489         DBGLOG(RSN, TRACE, ("IEEE 802.11: Ignore SA Query Request "
2490                "from unassociated STA " MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2491         return;
2492     }
2493     DBGLOG(RSN, TRACE, ("IEEE 802.11: Sending SA Query Response to "
2494            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2495
2496     prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter,
2497                       MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN);
2498
2499     if (!prMsduInfo)
2500         return;
2501
2502     prTxFrame = (P_ACTION_SA_QUERY_FRAME)
2503         ((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
2504
2505     prTxFrame->u2FrameCtrl = MAC_FRAME_ACTION;
2506     /* SA Query always with protected */
2507     prTxFrame->u2FrameCtrl |= MASK_FC_PROTECTED_FRAME;
2508
2509     COPY_MAC_ADDR(prTxFrame->aucDestAddr, prBssInfo->aucBSSID);
2510     COPY_MAC_ADDR(prTxFrame->aucSrcAddr, prBssInfo->aucOwnMacAddr);
2511     COPY_MAC_ADDR(prTxFrame->aucBSSID, prBssInfo->aucBSSID);
2512
2513     prTxFrame->ucCategory = CATEGORY_SA_QUERT_ACTION;
2514     prTxFrame->ucAction = ACTION_SA_QUERY_RESPONSE;
2515
2516     kalMemCopy(prTxFrame->ucTransId,
2517           prRxFrame->ucTransId,
2518           ACTION_SA_QUERY_TR_ID_LEN);
2519
2520     u2PayloadLen = 2 + ACTION_SA_QUERY_TR_ID_LEN;
2521
2522     //4 Update information of MSDU_INFO_T
2523     prMsduInfo->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;   /* Management frame */
2524     prMsduInfo->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
2525     prMsduInfo->ucNetworkType = prBssInfo->ucNetTypeIndex;
2526     prMsduInfo->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
2527     prMsduInfo->fgIs802_1x = FALSE;
2528     prMsduInfo->fgIs802_11 = TRUE;
2529     prMsduInfo->u2FrameLength = WLAN_MAC_MGMT_HEADER_LEN + u2PayloadLen;
2530     prMsduInfo->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
2531     prMsduInfo->pfTxDoneHandler = NULL;
2532     prMsduInfo->fgIsBasicRate = FALSE;
2533
2534     //4 Enqueue the frame to send this action frame.
2535     nicTxEnqueueMsdu(prAdapter, prMsduInfo);
2536
2537 }
2538
2539
2540 /*----------------------------------------------------------------------------*/
2541 /*!
2542 *
2543 * \brief This routine is called to process the 802.11w sa query action frame.
2544 *
2545 *
2546 * \note
2547 *      Called by: AIS module, Handle Rx mgmt request
2548 */
2549 /*----------------------------------------------------------------------------*/
2550 void
2551 rsnSaQueryAction (
2552     IN P_ADAPTER_T                  prAdapter,
2553     IN P_SW_RFB_T                   prSwRfb
2554     )
2555 {
2556     P_AIS_SPECIFIC_BSS_INFO_T       prBssSpecInfo;
2557     P_ACTION_SA_QUERY_FRAME         prRxFrame;
2558     P_STA_RECORD_T                  prStaRec;
2559     UINT_32                         i;
2560
2561     prBssSpecInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo;
2562     ASSERT(prBssSpecInfo);
2563
2564     prRxFrame = (P_ACTION_SA_QUERY_FRAME) prSwRfb->pvHeader;
2565     prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
2566
2567     if (prSwRfb->u2PacketLen < ACTION_SA_QUERY_TR_ID_LEN) {
2568         DBGLOG(RSN, TRACE, ("IEEE 802.11: Too short SA Query Action "
2569                "frame (len=%lu)\n", (unsigned long) prSwRfb->u2PacketLen));
2570         return;
2571     }
2572
2573     if (prRxFrame->ucAction == ACTION_SA_QUERY_REQUEST) {
2574         rsnSaQueryRequest(prAdapter, prSwRfb);
2575         return;
2576     }
2577
2578     if (prRxFrame->ucAction != ACTION_SA_QUERY_RESPONSE) {
2579         DBGLOG(RSN, TRACE, ("IEEE 802.11: Unexpected SA Query "
2580                "Action %d\n", prRxFrame->ucAction));
2581         return;
2582     }
2583
2584     DBGLOG(RSN, TRACE, ("IEEE 802.11: Received SA Query Response from "
2585            MACSTR"\n", MAC2STR(prStaRec->aucMacAddr)));
2586
2587     DBGLOG_MEM8(RSN, TRACE, prRxFrame->ucTransId,
2588            ACTION_SA_QUERY_TR_ID_LEN);
2589
2590     /* MLME-SAQuery.confirm */
2591
2592     for (i = 0; i < prBssSpecInfo->u4SaQueryCount; i++) {
2593         if (kalMemCmp(prBssSpecInfo->pucSaQueryTransId +
2594                   i * ACTION_SA_QUERY_TR_ID_LEN,
2595                   prRxFrame->ucTransId,
2596                   ACTION_SA_QUERY_TR_ID_LEN) == 0)
2597             break;
2598     }
2599
2600     if (i >= prBssSpecInfo->u4SaQueryCount) {
2601         DBGLOG(RSN, TRACE, ("IEEE 802.11: No matching SA Query "
2602                "transaction identifier found\n"));
2603         return;
2604     }
2605
2606     DBGLOG(RSN, TRACE, ("Reply to pending SA Query received\n"));
2607
2608     rsnStopSaQuery(prAdapter);
2609 }
2610
2611
2612 /*----------------------------------------------------------------------------*/
2613 /*!
2614 *
2615 * \brief This routine is called to process the 802.11w mgmt frame.
2616 *
2617 *
2618 * \note
2619 *      Called by: AIS module, Handle Rx mgmt request
2620 */
2621 /*----------------------------------------------------------------------------*/
2622 BOOLEAN
2623 rsnCheckRxMgmt (
2624     IN P_ADAPTER_T                  prAdapter,
2625     IN P_SW_RFB_T                   prSwRfb,
2626     IN UINT_8                       ucSubtype
2627     )
2628 {
2629     P_HIF_RX_HEADER_T               prHifRxHdr;
2630     BOOLEAN                         fgUnicast = TRUE;
2631     BOOLEAN                         fgRobustAction = FALSE;
2632
2633     prHifRxHdr = prSwRfb->prHifRxHdr;
2634
2635     if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) &&
2636         prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection  /* Use MFP */) {
2637
2638         P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame;
2639         prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T) prSwRfb->pvHeader;
2640
2641         if (prAssocReqFrame->aucDestAddr[0] & BIT(0))
2642             fgUnicast = FALSE;
2643
2644         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);
2645
2646         if (prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC) {
2647             /* "Dropped unprotected Robust Action frame from an MFP STA" */
2648             /* exclude Public Action */
2649             if (ucSubtype == 13 /* 0x1011: MAC_FRAME_ACTION */)
2650             {
2651                 UINT_8 ucAction = *prSwRfb->pucRecvBuff;
2652                 if (ucAction != CATEGORY_PUBLIC_ACTION && ucAction != CATEGORY_HT_ACTION) {
2653 #if DBG && CFG_RX_PKTS_DUMP
2654                     LOG_FUNC("QM RX MGT: UnProtected Robust Action frame = %d\n", ucAction);
2655 #endif
2656                     fgRobustAction = TRUE;
2657                     return TRUE;
2658                 }
2659             }
2660             if (fgUnicast && ((ucSubtype == 10 /* 0x1010: MAC_FRAME_DISASSOC */) || (ucSubtype == 12 /* 0x1100: MAC_FRAME_DEAUTH */))) {
2661                 LOG_FUNC("QM RX MGT: rsnStartSaQuery\n");
2662                 /* MFP test plan 5.3.3.5 */
2663                 rsnStartSaQuery(prAdapter);
2664                 return TRUE;
2665             }
2666         }
2667 #if 0
2668         else {
2669             if (fgUnicast && ((ucSubtype == MAC_FRAME_DISASSOC) || (ucSubtype == MAC_FRAME_DEAUTH))) {
2670                 /* This done by function handler */
2671                 //kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2672                 //      WLAN_STATUS_MEDIA_DISCONNECT,
2673                 //      NULL,
2674                 //      0);
2675             }
2676         }
2677 #endif
2678     }
2679     return FALSE;
2680 }
2681 #endif
2682